Cascade notation (..)
同一オブジェクトに対して複数の連続した処理を実行したい場合にカスケードノーテーション(..
)を使います。関数の実行に加えて、そのオブジェクトのフィールドにアクセスすることができます。
これにより、一時変数を作成する手間が省け、より流動的なコードを記述できるようになります。
以下のコードを考えてみましょう。
querySelector('#confirm') // Get an object. ..text = 'Confirm' // Use its members. ..classes.add('important') ..onClick.listen((e) => window.alert('Confirmed!'));
最初のメソッド呼び出しであるquerySelector()は、selectorオブジェクトを返します。
カスケード表記に続くコードは、このセレクターオブジェクトで動作し、返される可能性のある後続の値を無視します。
上記のコードは以下のコードと同じ意味です。
var button = querySelector('#confirm'); button.text = 'Confirm'; button.classes.add('important'); button.onClick.listen((e) => window.alert('Confirmed!'));
カスケードノーテーションをネストすることもできます。例えば以下のようなことができます。
final addressBook = (AddressBookBuilder() ..name = 'jenny' ..email = 'jenny@example.com' ..phone = (PhoneNumberBuilder() ..number = '415-555-0100' ..label = 'home') .build()) .build();
実際のオブジェクトを返す関数でカスケードを構築するように注意してください。たとえば、次のコードは失敗します。
var sb = StringBuffer(); sb.write('foo') ..write('bar'); // Error: method 'write' isn't defined for 'void'.
sb.write()メソッドはvoid型を返す(何も返さない)ので、voidに対してカスケード表記をすることはできません。
注: 厳密に言えば、カスケードの「ダブルドット」表記は演算子ではありません。これはDart構文の一部にすぎません。
カスケードノーテーションのメリット、使い所がいまいちピンとこないが、
void main(){ //カスケードノーテーション有り print([55,2,9,130,20]..add(30)..sort()); print("=============="); //カスケードノーテーション無し List<int> list4=[55,2,9,130,20]; list4.add(30); list4.sort(); print(list4); } /* [2, 9, 20, 30, 55, 130] ============== [2, 9, 20, 30, 55, 130] */
例えば、上記のリスト
[55,2,9,130,20]
に新しい要素
30
を加えてその後ソートして表示したい場合。
カスケードノーテーションを使うと、書こうと思えば一時変数を用意せずに書けるし、書こうと思えば1行で書ける。
(普通改行はするだろうけど。)
それに対してカスケードノーテーションが無いと、addメソッドもsortメソッドも返り値の型はvoid型なので、
必ず一時変数(list4)を用意する必要があるし、
list4.add(30).sort()
のようなチェーンするコード(関数を連続して呼び出すようなコード)は書けないので、上記サンプルのように最低でも4行必要、ということになる。
一応コード量は減るし、使わないといけない一時変数も減ってはいる。
これがメリットか。
結局これくらいのものなので絶対使わないといけない、というレベルのものではない。
ただ何も知らないと、コードが読めないので、
「どういうものなのか」
くらいは知っておかないといけない、ということか。
参考
https://dart.dev/guides/language/language-tour#cascade-notation-