Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
29
Help us understand the problem. What is going on with this article?
@lacolaco

Dartにおけるリスト(配列)のインスタンス生成による違い

More than 5 years have passed since last update.

Dartではリスト(配列)としてList<E>クラスを用いますが、インスタンス生成の方法によって内部の実装クラスが変化し、挙動に影響します。具体的に言うと、インスタンス生成の時点で、そのリストが「可変長かどうか」でクラスが使い分けられ、可変長でないリストに対してadd()clear()などのリスト長が変化するメソッドを呼び出すとエラーとなります。

というわけでDartにおけるリストのインスタンス生成方法についてまとめました。なお今回の例ではジェネリクスは省略していますが、本来はつけるべきです。

空(長さ0, 可変長)のリスト

単純な可変長配列として使うならこの方法です。

var list = new List();

もしくは

var list = [];

出力結果

[]

空(長さ10, 可変長)のリスト

インデックスが存在するのではじめからlist[0]等のアクセスが可能になります

var list = []..length = 10;

もしくは

var list = new List.generate(10, (i)=>null);

出力結果

[null, null, null, null, null, null, null, null, null, null]

初期値あり(長さ10, 可変長)

任意の値を入れたいのであれば

var list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

インデックスにより導出できる値であれば

var list = new List.generate(10, (i)=> i);

出力結果

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

空(長さ10, 固定長)

一つ目の落とし穴がここです。他の言語(例えばJava)ではListのコンストラクタに初期長さを与えるとメモリ確保だけしてくれるような感じですが、Dartで同じことをすると思わぬエラーが出ます。

var list = new List(10);

初期値あり(長さ10, 固定長)

var list = new List.filled(10, 1);

出力結果

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

ここで2つ目の落とし穴です。List.filledList.generateと違い、遅延実行ではなく、与えられたオブジェクトをそのままリストの初期値にします。そのため、参照型のオブジェクトを与えればすべての要素が同一オブジェクトとなります。つまり次のようなことになります。

var list = new List<List>.filled(2, []);
for (var i = 0; i < 2; i++) {
  list[i].add(i);
}

出力結果

[[0, 1], [0, 1]]

ちなみに、やりたかったことはこうです。

var list = <List>[[], []];
for (var i = 0; i < 2; i++) {
  list[i].add(i);
}

出力結果

[[0], [1]]

まとめ

var list = new List(); // 長さ0, 可変長
var list = new List(10); // 長さ10, 固定長
var list = []; // 長さ0, 可変長
var list = []..length = 10; // 長さ10, 可変長
var list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // 長さ10, 可変長
var list = new List.generate(10, (i)=>i); // 長さ10, 可変長
var list = new List.filled(10, 0); // 長さ10, 固定長

ちなみにList.fromにはオプション引数にgrowableがあるので、これをfalseにすると固定長として生成することが出来ます。

29
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
lacolaco
I play Angular and pray for Angular. No Breaking Changes No Life.
classi
学校の先生・生徒・保護者向けのB2B2Cの学習支援Webサービス「Classi(クラッシー)」 を開発・運営している会社です。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
29
Help us understand the problem. What is going on with this article?