質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

解決済

1回答

977閲覧

Dart : リストをconstで宣言すると発生するエラーについて

moriman

総合スコア615

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2020/11/13 01:18

//sample1(Dartpad) var ol=['Tokyo', 'Delhi', 'Shanghai', 'Mumbai', 'Beijing']; void main(){ List<String> cities=ol; cities.sort(); print("ol==>$ol"); print("cities==>$cities"); } /* ol==>[Beijing, Delhi, Mumbai, Shanghai, Tokyo] cities==>[Beijing, Delhi, Mumbai, Shanghai, Tokyo] */
//sample2(Dartpad) const ol=['Tokyo', 'Delhi', 'Shanghai', 'Mumbai', 'Beijing']; void main(){ List<String> cities=ol; cities.sort(); print("ol==>$ol"); print("cities==>$cities"); } /* 実行時エラー発生↓。 Uncaught Error: Unsupported operation: sort */

サンプルコードを動かそうとしていて、たまたま上記のようなエラーが出たのですが、
sample2でエラーが出る理由がわかりません。
sortメソッドがサポートされていない、と出てるんですが、
sample1が普通に動いている時点でsortメソッドは使えると思うのですが。

要るのかどうかよくわかりませんが一応サンプルのソースは
https://medium.com/@davidmorgan_14314/the-mutability-tax-6403d84f21c0
上記で、イミュータブルの話です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

constは変更不可なので、破壊的メソッドであるsort()をしようとしたらエラーが出るのは当然です。

なお、finalつけたリストの要素は変更可能なので、これと混同されたのかもしれません。

参考: A tour of the Dart language - Final and const
Note: Although a final object cannot be modified, its fields can be changed. In comparison, a const object and its fields cannot be changed: they’re immutable.
(finalオブジェクトの要素は変更可能だけど、constオブジェクトは要素も含めて変更不可)

投稿2020/11/13 03:44

toast-uz

総合スコア3266

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moriman

2020/11/13 04:48

回答を頂きましてありがとうございます。 質問文のsample2ではolはconstで宣言されていますが、citiesは変数(var)として宣言されています。 そして cities.sort(); という形で変数に対してsort()メソッドを呼び出しています。 ここから私の現在の認識なのですが、Dartでリスト(List型)は(Swiftでいうところの)参照型なので、 List<String> cities=ol; のように代入すると、citiesはolと同じ参照を指すことになる。 なのでcitiesに対する操作は結局olに対して同じ操作をすることになる。 でもolはconstで宣言されているので、その操作は許されない。 という理解で問題ないでしょうか? Dartのドキュメント内で(Swiftの)値型・参照型のような定義・説明が見当たらないので、 結局Swiftの定義をDartに当てはめて考えて上記のような認識になっている状況です。 この、「値型・参照型」などの定義はDartドキュメント内にありますでしょうか。 それからここら辺を調べている中で「シャローコピー・ディープコピー」という言葉が出てきたのですが、 ただの代入のように、代入先への操作(再代入を除く)が代入元の結果にも反映される(いわゆる参照型)になるようなコピーがシャローコピー、 そうではなく、値自体がコピーされるので代入先への操作は代入元へは反映されないような(いわゆる値型)コピーがディープコピー、 という理解で問題ないでしょうか。 ディープコピー、シャローコピーの定義は公式ドキュメント内にありましたでしょうか。 (一応そこら辺(クラスらへん)は目を通したつもりなのですが) 確かに「finalオブジェクトのフィールドは修正可能だが、constオブジェクトとそのフィールドは修正不可能である。constオブジェクトはimmutableだから。」 と書いてあります。 まさにimmutableとは何なのか、ということを調べていたのですが、ここ(公式ドキュメントのお示しいただいた箇所)にはimmutableの定義は直接的に明示されてはいません。どこかに公式ドキュメント内でimmutableの定義ってありますでしょうか?
toast-uz

2020/11/13 09:51 編集

基本的にはご理解の通りです。私的には、DartでのListコピーは、(1)変数だけのコピー(参照渡し的な概念)、(2) immutableな中身(intとかStringとか)まで含めたコピーであるList.of、(3) 中身もmutableオブジェクトでそこまで含めて完全コピーすること(メソッド無く自作でcloneメソッド作る必要あり)の、3種で、(1)ではなく(2)をシャローコピーと呼んでおり、そういう呼び方が多いようです。そこだけ違います。Pythonも(1)の変数代入、(2)のcopy.copy、(3)のcopy.deepcopyの3段階があり、似たようなものです。 基本的にDartはJavaっぽい装いを後かから仕立てているものの、型指定の無い言語が元になっているため、immutableな変数を使い回すといった高尚なことには向いておりません。私自身は、自分でコーディングする際は、小さいクラスはなるべくimmutableに設計していますが、組み込みオブジェクトが基本的にmutableで破壊的なメソッドが多く、とても苦労します。DateTimeがバリバリにmutableな時点で半分泣いて、DateTimeもどきなimmutableクラスを新規に作ったりしています。Swiftは知りませんが、Swiftをたまに覗き見すると、Swift慣れした人にはDartはイラつく言語だろうな、と思います。Flutterに採用されなきゃ消えていたと思います。笑 よって、Dart公式で、まともなimmutableの解説は期待しないほうがよいです。偉い人はfreezedとかいうライブラリを作ってがんばったりしていますね。
moriman

2020/11/17 01:51

色々と教えていただきましてありがとうございます。 もう少し調べてみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問