「Flutter実践開発」本2.4参照
演算子
基本的な演算子に関しては割愛
カスケード記法
単一のオブジェクトに対して連続して操作を行う際に利用する記法
イメージとしてはvbaなどに存在しているwithに似ている
final sb = StringBuffer()
..write('Hello')
..write(', ')
..write('Dart');
print(sb.toString());
// => Hello, Dart
カスケード記法を用いた連続呼び出しの途中ではセミコロンによる行の終端まで続く。
ということは、サンプルで改行しているのは見やすさのためだけでこんな書き方でも動作するのかな?とやってみたらちゃんと動いた
final sb = StringBuffer()..write('Hello')..write(', ')..write('Dart');
print(sb.toString());
// => Hello, Dart
あれ、ではこういう書き方はできるのだろうか?
final sb = StringBuffer().write('Hello').write(', ').write('Dart');
print(sb.toString());
行けそうな気はしたけれど、これはエラーになった。
どうやら、StringBufferのwriteメソッドは戻り値がvoid型のようでメソッドチェーンが使えない。
thisを返却するようなメソッドであれば上記のような記載はできるのだが。
となると、カスケード記法では戻り値をつなげているのではなく、やはり元となるオブジェクトに対してメソッド呼び出しをしているということになる。
この場合、戻り値は無視されるようだ。
メソッドチェーンが使えないような状態において利用するのに重宝しそうだ
Spread演算子
コレクションに対して"..."を用いることで内容の展開をしてくれる
JavaScriptでもなんか見たことがある書き方だ
final list1 = [1,2,3];
final map1 = {'field1':10, 'field2':20};
print(...list1);
print(...map1);
試しにやってみたが、見事にエラーになった。
これは、DartのSpread演算子が、あくまでリテラル内でのみ利用可能なため。
単純なコレクション内データの展開に使えるわけではないようだ。
このあたり、Caludeに聞いてみると
// もしスプレッド演算子が使えたら...
void calculate(int a, int b, int c) {
print(a + b + c);
}
void main() {
final list1 = [1, 2, 3];
final list2 = [1, 2]; // 要素数が足りない
final list3 = [1, 2, 3, 4]; // 要素数が多い
// calculate(...list1); // これは型チェックが難しい
// calculate(...list2); // 引数が足りない?
// calculate(...list3); // 引数が多すぎる?
}
Dartは「明示的で予測可能なコード」を重視する言語です。スプレッド演算子を関数呼び出しで使えないのは制限というより、型安全性と可読性を保つための設計判断ですね
とのことだった。
なるほどである。
".."や"..."などは言ってしまうと省略記法になって、パット見で認知的負荷を上げているような気がする。
これは、単純にこの書き方に慣れていないだけといえばそうなのかもしれないが。。。
このあたり、オールドタイプであると認識せざるを得ない