天天看點

從dill角度解釋dart const 與final的差別

const和final來修飾屬性field都表示對象不可變。但是const在編譯期起到作用。而final則是在運作期起作用。

可以通過dart sdk源碼中提供的dump_kernel工具來更深刻地認識一下。

dart編譯的過程,會先掃描dart檔案,生成ast樹,然後生成dart intermidate language file即 app.dill,然後根據aot或者jit生成不同的産物。可以看一下const在ast轉換成dil檔案後,産物中的形态。

static const field asy::StreamTransformer<core::Object, res10::Result<core::Object>> captureStreamTransformer = #C15926;
    static const field asy::StreamTransformer<res10::Result<core::Object>, core::Object> releaseStreamTransformer = #C15927;
    static const field str17::StreamSinkTransformer<core::Object, res10::Result<core::Object>> captureSinkTransformer = #C15928;
    static const field str17::StreamSinkTransformer<res10::Result<core::Object>, core::Object> releaseSinkTransformer = #C15929;
           

比如這是某個類的dil在dump_kernel後的産物中的形态。可以看到const修飾的變量轉換成了 [#C數字]開頭的形式。

從dill角度解釋dart const 與final的差別

裡面有個常量區域,其中放的全是這些常量符号。

從dill角度解釋dart const 與final的差別

可以看到const修飾的常量,compile的時候就已經做了轉換

從dill角度解釋dart const 與final的差別

可以看到指向cap2::中的用const修飾的constuctor構造函數。

我們再看一下final修飾的變量,用關鍵字final搜尋。

從dill角度解釋dart const 與final的差別

沒有看到特殊的處理。

const A a = A(),此時A的構造函數必須要有const修飾,如果沒有,那麼ast dump到二進制dill檔案的過程中ConstantsTransformer會報錯。

含有code example的解釋見如下連結。

Dart – Const And Final Keyword

為什麼要這樣設計呢?

思考一番。會發現constant池子裡的對象可以被所有這些static const共用,這樣節省了記憶體和dill的體積。