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引数 | 名前付き引数:growable | bool | 可変長の場合は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引数 | 名前付き引数:growable | bool | 可変長の場合は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引数 | 必須 | Iterable | List等反復可能な要素。 |
第2引数 | 名前付き引数:growable | bool | 可変長の場合は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引数 | 名前付き引数:growable | bool | 可変長の場合は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引数 | 必須 | Iterable | List等反復可能な要素。 |
第2引数 | 名前付き引数:growable | bool | 可変長の場合は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引数 | 必須 | Iterable | List等反復可能な要素。 |
コーディングで確認。
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
コメント