【Flutter/Dart】spread記法(…)ドット3つ/使い方/基礎から実践

最終更新日

Dartの基本文であるspread記法(…)について調べてまとめました。基礎から実践までサンプルがあります。動かない場合はコメントください。

動かすにはDartpadを使用してください。

spreadとは

spreadとは、バージョン2.3以降に新しく追加された要素です。List・Set・Mapの要素を拡張するために使用します。

公式サイト

https://dart.dev/guides/language/language-tour#lists

基礎

List

Dart 2.3より前では、addAllを使いリストを組み合わせていました。しかし、spreadを使用することでaddAllを使うことなく同じことができるようになります。

下記の例では、addAllを使うことなくmainのリストにresultのリストを組み合わせています。

void main(){
  List<int> main = [1, 2, 3];
  List<int> result = [0, ...main];
  print(result);
  }

インスタンス

二つのリストクラスのインスタンスを組み合わせるためにしようすることも可能です。

void main(){
  List<int> main = [1, 2, 3];
  List<int> sub = [4, 5];
  List<int> result = [...main, ...sub];
  print(result);
  }

ネスト

ネストされたものも可能です。これも、リストを追加できています。

void main(){
  List<int> l1 = [1, 2, 3];
  List<int> l2 = [4, 5];
  List<int> result = [...[0, ...l1, ...l2], 6];
  print(result);
  }

if文を使用する

if文を使用して、Listクラスが連結する必要があるかどうかを判断することも可能です。

void main(){
  List<int> l1 = [1, 2, 3];
   List<int> l2 = [4, 5];
  bool condition = false;
  List<int> result = [...l1, if (condition) ...l2];
  print(result);
  }

Future

awaitの後にFuture追加して使用することもできます。

void main(){
  Future<List<int>> l1 = Future.value([1, 2, 3]);
Future<List<int>> l2 = Future.value([3, 4, 5]);
  List<int> result = [...await l1, ...await l2];
  print(result);
  }

Nullで使用する

nullで使用する場合では、エラーが起きます。以下は、わざとエラーを起こしています。

void main(){
  List<int> l1 = [1, 2, 3];
  List<int> nullList = null;
  List<int> result = [...l1, ...nullList];
  print(result);
  }
エラー内容
Unhandled exception:
  NoSuchMethodError: The getter 'iterator' was called on null.

エラーを起こさずに書く方法についてまとめています。こちらをご覧ください。

Set

SetクラスでもSpread演算子を使用することができます。複数のインスタンスを組み合わせることが可能で、Setには一意の要素が必要であるため、結果は全てSetインスタンスの和集合になります。

void main(){
Set<int> s1 = {1, 2, 3};
  Set<int> s2 = {3, 4, 5};
  Set<int> result = {...s1, ...s2};
  print(result);
}

ネスト

ネストされたものも使用可能です。

void main(){
  Set<int> s1 = {1, 2, 3};
  Set<int> s2 = {3, 4, 5};
  Set<int> result = {...{...s1, ...s2}, 5, 6};
  print(result);
  }

Future

awaitの後にFuture追加して使用することもできます。

void main(){
  Future<Set<int>> s1 = Future.value({1, 2, 3});
  Future<Set<int>> s2 = Future.value({3, 4, 5});
  Set<int> result = {...await s1, ...await s2};
  print(result);
  }

Nullで使用する

nullで使用する場合では、list同様エラーが起きます。以下は、わざとエラーを起こしています。

void main(){
  Set<int> s1 = {1, 2, 3};
  Set<int> nullSet = null;
  Set<int> result = {...s1, ...nullSet};
  print(result);
}
エラー内容
Unhandled exception:
  NoSuchMethodError: The getter 'iterator' was called on null.

Map

MapクラスでもSpread演算子は使用することができます。

下記の例では、重複した古いインスタンスは上書きされます。

void main(){
  Map<int, String> m1 = {1: '1-1', 2: '1-2'};
  Map<int, String> m2 = {2: '2-2', 3: '2-3'};
  Map<int, String> result = {...m1, ...m2};
  print(result);
}

ネスト

ネストされたものも使用可能です。

void main(){
  Map<int, String> m1 = {1: '1-1', 2: '1-2'};
  Map<int, String> m2 = {2: '2-2', 3: '2-3'};
  Map<int, String> result = {...{...m1, ...m2}, 3: '3', 4: '4'};
  print(result);
  }

Future

awaitの後にFuture追加して使用することもできます。

void main(){
  Future<Map<int, int>> future1 = Future.value({1: 1, 2: 2});
  Future<Map<int, int>> future2 = Future.value({3: 3});
  Map<int, int> result = {...await future1, ...await future2};
  print(result);
  }

Nullで使用する

nullで使用する場合では、エラーが起きます。以下は、わざとエラーを起こしています。

void main(){
  Map<int, String> m1 = {1: '1-1', 2: '1-2'};
  Map<int, String> nullMap = null;
  Map<int, String> result = {...m1, ...nullMap};
  print(result);
  }
エラー内容
Unhandled exception:
  NoSuchMethodError: The getter 'entries' was called on null.

参考

https://www.woolha.com/tutorials/dart-using-triple-dot-spread-operator-examples

fem