於編譯期進行包裝,執行階段不會產生額外物件(零額外負荷);用途是為既有類型建立一組全新靜態介面,限制可呼叫的方法。
與一般 Extension 的差異:普通擴充會對原始型別所有實例新增方法;Extension Type 僅在物件靜態型別為該擴充型別時生效。
// int 代表【表示型別】,id 是底層原始欄位名稱
extension type IdNumber(int id) {
operator <(IdNumber other) => id < other.id;
}Code language: Dart (dart)
自動產生內容:
- 隱性建構子
IdNumber(int id) - 取值方法:
int get id
兩大模式(最常使用)
1)不透明模式
介面隔離|建議用於商務規範限制
不加上 implements
隔離底層類別原生方法,達到介面限制效果
無法直接與底層型別互相指派
extension type IdNumber(int id) {
operator <(IdNumber other) => id < other.id;
}
void main() {
final id = IdNumber(100);
id + 5; // 編譯錯誤:沒有 + 運算子,已遮蔽 int 的加法
final int raw = id; // 錯誤,禁止直接指派
final int raw = id as int; // 透過強制轉型取得底層數值
}Code language: PHP (php)
2)透明模式
implements 表示型別
自動繼承底層類別所有成員,僅能新增或覆寫方法
extension type Num(int v) implements int {
Num square() => Num(v * v);
}
void main() {
final n = Num(5);
print(n.isNegative); // 可直接呼叫 int 原生方法
}Code language: Dart (dart)
建構子撰寫方式
底層括號為預設建構子,可以使用 ._ 私有化隱藏
extension type Id._(int _raw) {
// 外部只能呼叫此具名建構子,禁止直接 Id(xxx)
Id.create(int value) : _raw = value;
}Code language: JavaScript (javascript)
支援項目:方法、取值器、設值器、運算子
禁止項目:實例變數、抽象成員
Extension Types
Previous: 擴充方法(Extension methods)
Next: Class Modifiers 類別修飾子