Primary Constructors(主建構函式)

認識概念

最低支援 Dart 語言版本 3.13

作用:在類別開頭單行同時宣告欄位 + 主建構函式,大量減少樣板程式碼;執行期行為與傳統建構函式完全一致,僅簡化語法。

  1. Declaring parameters(宣告型參數):類別開頭參數帶 var / final → 自動產生同名實體欄位。
  2. Non-declaring parameters(一般參數):開頭參數無 var/final → 僅為建構傳入參數,不會建立類別欄位。
  3. In-body constructors(類別內建構函式):寫在類別大括號內的具名、工廠、重新導向建構函式。
  4. 強制規則:擁有主建構函式的類別,不能存在其他非重新導向的產生式建構函式,確保所有實體都必須經過主建構函式建立。

傳統寫法 vs 主建構簡寫對照

// 傳統冗餘寫法
class Point {
  int x;
  int y;
  Point(this.x, this.y);
}

// 主建構簡寫
class Point(var int x, var int y);Code language: JavaScript (javascript)

欄位自動產生規則

1. 加上 var / final

自動建立實體欄位

直接在類別名稱後面的括號中撰寫欄位變數

// x、y 自動成為類別成員變數
class Point(var int x, final int y);

void main() {
  final p = Point(10, 20);
  print(p.x); // 10
  print(p.y); // 20
  // p.y = 30; // 編譯錯誤,y 宣告為 final 不可修改
}Code language: JavaScript (javascript)

執行上述程式會報錯

D:\dartdemo\firstdart\bin>dart run
Building package executable...
Failed to build firstdart:firstdart:
firstdart.dart:2:13: Error: This requires the experimental 'primary-constructors' language feature to be enabled.
Try passing the '--enable-experiment=primary-constructors' command line option.
class Point(var int x, final int y);
            ^^^
firstdart.dart:2:12: Error: This requires the experimental 'primary-constructors' language feature to be enabled.
Try passing the '--enable-experiment=primary-constructors' command line option.
class Point(var int x, final int y);
           ^
firstdart.dart:2:36: Error: This requires the experimental 'primary-constructors' language feature to be enabled.
Try passing the '--enable-experiment=primary-constructors' command line option.
class Point(var int x, final int y);Code language: JavaScript (javascript)

錯誤原因:class Point(var int x, final int y); 這種主建構簡寫(Primary Constructors)屬於 Dart 的實驗性功能,目前穩定版 Dart 預設關閉,直接執行會出現語法錯誤。

當前時間為 2026 年 7 月 10 日 14:55,讀者閱讀本文時,Dart 或許已推出正式新版本,預設直接支援此語法。

可使用以下指令臨時測試

dart run --enable-experiment=primary-constructors

2. 無 var / final

僅作暫存參數,不會產生欄位

class User(String name) {
  // print(name); // 類別內可直接存取參數,但不會建立 this.name 欄位
  final String msg = "Hi $name"; // 編譯錯誤
}

void main() {
  final u = User("Tom");
  // print(u.name); // 編譯錯誤,不存在 name 欄位
}Code language: JavaScript (javascript)

Previous:

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *