はじめに
Dart
はコンストラクタの定義方法がありすぎです。
なので備忘録も兼ねてまとめていこうと思います。
前提
NullSafety
を適用した場合の書き方になります。
専門用語が出てくるのでおさらいしておきます。
NonNullable
Null非許容型 のことを指します。普通の変数のことです。
例) int a; String b; など
Nullable
Null非許容型(オプショナルともいう)のことを指します。
例) int? a; String? b; ?をつけて変数宣言するやつ
NonNullableかそうでないかで実装方法が全然変わりますので注意が必要です。
基本パターン
/* クラス側 */ class TestClass1 { late int hoge1; late String hoge2; // コンストラクタ TestClass1(int param1, String param2) { hoge1 = param1; hoge2 = param2; } } // 呼び出し側 var test = TestClass(1, "ABC");
C#やJavaだとこういう書き方しますよね🤐
呼び出し側は全ての引数に対して値をセットしないとエラーになります。
クラス側はNonNullableな変数にはlate
をつけないとエラーになります。
※NullSafety
を適用してる場合のみ
this.で省略可
変数に代入だけならthis.
を使うともっと簡略して書くことができます。
/* クラス側 */ class TestClass2 { int hoge1; String hoge2; // コンストラクタ TestClass2(this.hoge1, this.hoge2); } /* 呼び出し側 */ var test = TestClass(1, "ABC");
これは他言語にはない仕様なので初見だと「コンストラクタなの?」って思いますよね😓
しかもlate
をつけなくてもいいみたいです。
以降の引数指定の全てでこの方法が使えますので、覚えておきましょう。
オプショナル引数 ( [引数1, 引数2] )
実装方法
[ ]
の間に引数を定義します。
/* クラス定義 */ TestClass1(this.hoge1, [String? hoge, int param1 = 0]) { } /* 呼び出し側 */ var test1 = new TestClass1(1); // オプショナル引数を省略 var test2 = new TestClass1(2, "ABC"); // 1個だけ指定 var test3 = new TestClass1(3, "DEF", 3); // 全部指定
NonNullableな引数は初期値が必要
引数がNonNullableだと初期値を入れないとエラーになります。
// NG TestClass1([int param1]) { } // NonNullableなのに初期値がないからエラー // OK TestClass1([int param1 = 0]) { } // NonNullableだけど初期値があるからOK // OK TestClass1([int? param1]) { } // Nullableだから初期値がなくてもOK
ちなみにNGパターンだと以下のエラーメッセージが発生します。
The parameter 'param1' can't have a value of 'null' because of its type, but the implicit default value is 'null'. Try adding either an explicit non-'null' default value or the 'required' modifier.
まとめ
- 基本パターンと併用して引数が定義可
- 呼び出し側で引数を省略可
- NonNullableな引数は初期値が必須
ラベル付き引数 ( {引数1, 引数2} )
実装方法
{ }
の間に引数を定義します。
/* クラス側 */ TestClass1({int? param1, String param2 = "Hello"}) {} /* 呼び出し側 */ // ① 「引数名: 値 」で指定していく var test1 = new TestClass1(param1: 0, param2: "ABC"); // ② 引数順でなくてもいい var test2 = new TestClass1(param2: "ABC", param1: 0); // ③ 省略もできる var test3 = new TestClass1(param2: "ABC");
NonNullableな引数は初期値が必須
オプショナル引数と同様にNonNullableは初期値が必要です。
class TestClass2 { // これはエラー TestClass2({int param}) {}
// これならOK TestClass2({int param = 0}) {} }
requiredをつけると省略不可にできる
引数省略可がデフォルトですが、逆に一部の引数は必須にしたい場合もありますよね?
そういうときはrequiredをつけます。
requiredをつけるとNonNullableな引数も初期値が不要になります。
// これはエラー TestClass1({int param1}) { // NonNullableは初期値が必要 } // これはOK TestClass1({required int param1}) { }
以前は@をつけて@requiredという指定方法でしたが、現在は@なしになりました。
古い記事とかだとその名残が残っているので注意が必要ですね。
まとめ
- 引数名:値の形式で引数をセットする
- 引数指定の順序不問になった
- 引数指定は省略可だがrequiredをつけることで必須にもできる
- NonNullableな引数は初期値が必要
- NonNullableな引数はrequiredをつけると初期値が不要