Dart Listクラスのコンストラクタ

Dar言語StreamクラスtoSet()メソッドDart

Dart Listクラスのコンストラクタについてメモ書き。

概要

Listクラスは配列を扱うクラス。公式サイトはこちら
Listクラスには複数のコンストラクがある。大きく分けて以下2つに分類される。

  • 固定長(Fixed-length list)の配列
  • 可変長(Growable list)の配列

デフォルトは可変長の配列。[ ]で作成する。
以下例ではint型の配列を作成している。

final gList = <int>[1, 2];

次はList.filled()コンストラクタで固定長の配列を確認。
固定長の配列は要素数を変更するとエラーになる。add()メソッドで要素を追加してみる。

void main() {
  try {
    // 固定長の配列を作成
    final gList = List<int>.filled(2, 0);
    print(gList);
    // 配列に要素を追加。エラーが発生する
    gList.add(5);
  } catch (e) {
    print(e.toString());
  }
}

実行結果。
1行目は配列の出力結果。
2行目は固定長の配列に要素を追加したことで発生したエラー。

[0, 0]
Unsupported operation: Cannot add to a fixed-length list

可変長の配列でも、for文等で反復処理をしている最中に要素数を変更するとConcurrentModificationErrorが発生する。

以下で各コンストラクタを確認する。

List.empty()

List.empty()コンストラクタは空の配列を作成する。
引数は以下の通り。

引数必須/オプション/名前付き引数説明
第1引数名前付き引数:growablebool可変長の場合はtrueを指定。
固定長の場合はfalseを指定。
デフォルトはfalse。

コーディングで確認。

void main() {
  try {
    // 可変長配列
    final empListGrow = List<int>.empty(growable: true);
    empListGrow.add(1);
    print(empListGrow);

    // 固定長配列
    final empListFixed = List<int>.empty();
    empListFixed.add(1);
    print(empListFixed);
  } catch (e) {
    print(e.toString());
  }
}

1行目はempty(growable: true)の出力結果。add()メソッドで要素を追加している。
2行目はempty()の出力結果。デフォルトがgrowable: falseなので要素を追加するとエラーになる。

[1]
Unsupported operation: Cannot add to a fixed-length list

List.filled()

List.filled()コンストラクタは固定長配列を生成する。

引数必須/オプション/名前付き引数説明
第1引数必須int配列の要素数。
マイナスは指定できない。
第2引数必須E(ジェネリック型。E=配列の要素)配列の要素数分、第2引数で埋める。
第3引数名前付き引数:growablebool可変長の場合はtrueを指定。
固定長の場合はfalseを指定。
デフォルトはfalse。

コーディングで確認。

void main() {
  try {
    // 固定長配列
    final listFixed = List<String>.filled(5, "a");
    print(listFixed);

    // 可変長配列
    final listFixedGrow = List<dynamic>.filled(5, "a", growable: true);
    listFixedGrow.add(1);
    print(listFixedGrow);
  } catch (e) {
    print(e.toString());
  }
}

1行目はfilled(5, “a”)の結果。
2行目は第3引数のgrowable: trueで可変長配列を有効にし、add(1)で要素を追加した結果。

[a, a, a, a, a]
[a, a, a, a, a, 1]

List.from()

List.from()コンストラクタは引数として渡されたIterableな要素をキャスト(型変換)できる。

引数必須/オプション/名前付き引数説明
第1引数必須IterableList等反復可能な要素。
第2引数名前付き引数:growablebool可変長の場合はtrueを指定。
固定長の場合はfalseを指定。
デフォルトはtrue。

コーディングで確認。

void main() {
  try {
    // Setのdynamic型
    Set<dynamic> setTest = {"test", "test1"};
    print(setTest);

    // ListのString型にキャスト
    final listTest = List<String>.from(setTest);
    print(listTest);
  } catch (e) {
    print(e.toString());
  }
}

実行結果。
1行目はSetのdynamic型で出力。
2行目はキャストしたListのString型で出力。

{test, test1}
[test, test1]

ただ、バグの温床になりやすいので注意。
以下のようにdynamic型に文字列(String)と数値(int)が含まれているものをString型に変換しても文法チェックで引っ掛からない。

void main() {
  try {
    // Setのdynamic型。数値(int)を加える。
    Set<dynamic> setTest = {"test", "test1", 1};
    print(setTest);

    // ListのString型にキャスト。数値が含まれているにも関わらず、文法チェックに引っ掛からない。
    final listTest = List<String>.from(setTest);
    print(listTest);
  } catch (e) {
    print(e.toString());
  }
}

実行結果。
2行目で例外が発生している。

{test, test1, 1}
type 'int' is not a subtype of type 'String'

List.generate()

List.generate()コンストラクタは要素数を加工した値を配列に入れられる。
要素数に対してマイナスは指定できない。

引数必須/オプション/名前付き引数説明
第1引数必須int要素数。
第2引数必須E generator(int index)要素から値を作成するジェネレーター。
第3引数名前付き引数:growablebool可変長の場合はtrueを指定。
固定長の場合はfalseを指定。
デフォルトはtrue。

コーディングで確認。

void main() {
  try {
    // 配列のインデックスに1をプラス
    final listGen =
        List<num>.generate(3, (int index) => index + 1, growable: false);
    print(listGen);
  } catch (e) {
    print(e.toString());
  }
}

実行結果。
配列のインデックスは0から始まる。この例ではインデックスに1をプラスした値を配列に入れている。

[1, 2, 3]

List.of()

List.of()コンストラクタは引数として渡されたIterableな要素を配列にできる。
List.from()と違ってキャストは文法チェックで引っ掛かる。

引数必須/オプション/名前付き引数説明
第1引数必須IterableList等反復可能な要素。
第2引数名前付き引数:growablebool可変長の場合はtrueを指定。
固定長の場合はfalseを指定。
デフォルトはtrue。

コーディングで確認。

void main() {
  try {
    // SetのString型
    Set<String> setTest = {"test", "test1"};
    print(setTest);

    // ListのString型
    final listTest = List<String>.of(setTest);
    print(listTest);
  } catch (e) {
    print(e.toString());
  }
}

実行結果。
1行目はSetの出力。
2行目、引数として渡したSetがListで出力されている。

{test, test1}
[test, test1]

List.unmodifiable()

List.unmodifiable()コンストラクタは引数として渡されたIterableな要素をキャスト(型変換)できる。
List.from()と違い、こちらは可変長配列にできない。

引数必須/オプション/名前付き引数説明
第1引数必須IterableList等反復可能な要素。

コーディングで確認。

void main() {
  try {
    // Setのdynamic型
    Set<dynamic> setTest = {"test", "test1"};
    print(setTest);

    // ListのString型
    final listTest = List<String>.unmodifiable(setTest);
    print(listTest);

    // 要素を追加
    listTest.add("a");
  } catch (e) {
    print(e.toString());
  }
}

実行結果。
1行目はSetのdynamic型で出力。
2行目、引数として渡したSetのdynamic型をListのString型で出力している。
3行目、要素を追加したので例外が発生。

{test, test1}
[test, test1]
Unsupported operation: Cannot add to an unmodifiable list

コメント

タイトルとURLをコピーしました