コンパイル時にラップされ、実行時に追加オブジェクトが生成されません(ゼロコスト)。既存の型に新しい静的インターフェースを定義し、利用可能なメソッドを制限するために使用します。
通常のExtensionとの違い:標準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
代表的な2つのモード(よく使われる)
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 クラス修飾子