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

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

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

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

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

Q&A

解決済

2回答

5808閲覧

Dartの..で()がないとエラーになる

copp

総合スコア11

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

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

0グッド

0クリップ

投稿2020/02/15 10:12

前提・実現したいこと

エラーメッセージはprint文のコメントを外した状態です

###ここに質問の内容を詳しく書いてください。
現在、Flutter(dart)を勉強しておりますが、dartの動きがよく分からなかったので質問させてください。
2みたいソースコードがサンプルに記載されており、1の簡略が2になるのだろうと想像しました。
その際に3,4でも可能では思い、確認した所エラーになりました。
shuffle()の戻り値がvoidだからエラーになるのかなとエラーメッセージから想像したのですが
2が大丈夫で3,4がエラーになる理由がよくわかりませんでした。

お手数ではございますが、御教唆お願いいたします。

発生している問題・エラーメッセージ

lib/test.dart: Warning: Interpreting this as package URI, 'package:flutter_tutorial_layout/test.dart'.
lib/test.dart:14:25: Error: This expression has type 'void' and can't be used.
print((_list.shuffle()).first);
^
lib/test.dart:14:27: Error: The getter 'first' isn't defined for the class 'void'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'first'.
print((_list.shuffle()).first);
^^^^^
lib/test.dart:18:16: Error: This expression has type 'void' and can't be used.
print(_list..shuffle().first);
^
lib/test.dart:18:26: Error: The getter 'first' isn't defined for the class 'void'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'first'.
print(_list..shuffle().first);

該当のソースコード

dart
void main() {
var _list = <String>['one', 'two', 'three'];

// 1. 簡略化する前
_list.shuffle();
print(_list.first);

// 2. 簡略化後
print((_list..shuffle()).first);

// 3. エラー1(.. -> .)
// shuffle()の戻り値がvoidの為、エラーになるのだと思うのですが
// ..(カスケード)だとvoidではなく_listとして認識してくれるのでしょうか?
// print((_list.shuffle()).first);

// 4. エラー2(_list..shuffle()を()から外した)
// こちらも同様に()を外すと_listではなくvoidとなるのでしょうか?
// print(_list..shuffle().first);
}

ここにより詳細な情報を記載してください。
dart version 2.7.0

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

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

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

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

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

guest

回答2

0

ベストアンサー

3の_list.shuffle().firstは単純にshuffle()の戻り値がvoidのため、エラーになります。

4の_list..shuffle().firstshuffle().firstがカスケードの範囲として認識されます。なので、shuffle()の戻り値voidfirstしており、エラーになります。
一方、2の(_list..shuffle()).firstではshuffle()のみがカスケードの範囲として認識されるので、first_listに対して実行されます。


カスケード記法は、スコープ構造に置き換えるとわかりやすいかもです。
次のカスケード..までか、カッコ内()がカスケードの範囲として認識されるようです

_list..shuffle();は以下のように置き換えられる

(arg){ // リスト自体がシャッフルされ、戻り値voidは使わない arg.shuffle(); // リストを返す return arg; }(_list);

2のprint((_list..shuffle()).first);は以下のように置き換えられる

print( (arg){ // リスト自体がシャッフルされ、戻り値voidは使わない arg.shuffle(); // リストを返す return arg; }(_list) .first // リストの先頭を返す );

4のprint(_list..shuffle().first);は以下のように置き換えられる

print( (arg){ // リスト自体がシャッフルされ、戻り値voidにfirstしているからエラー arg.shuffle().first; // リストを返す return arg; }(_list) );

参考情報:How do method cascades work exactly in dart?

It helps to think of ".." as not really an operator, but more like a scoping construct (like parentheses). It creates a new scope from the ".." to either the next "..", or the first other scope delimiter (";", ")", "}" or similar).

Basically, a..b().c() is the same as (t){t.b().c(); return t;}(a)


おまけですが、4のようなa..b().c()を使いたいケースを考えてみました...

var _list = <List<String>>[['one', 'two', 'three'],['four', 'five', 'six']]; print(_list..first.shuffle()); print((_list..shuffle()..first.shuffle()).first.first);

投稿2020/02/15 21:51

編集2020/02/15 22:23
popobot

総合スコア6586

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

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

copp

2020/02/16 02:21

詳しいご返答ありがとうございます。 大変参考になりました。 おまけのケースも(_list..shuffle()).first は _list..shuffle()..first と書く事もできるのだと気づかせて頂きました。 腑に落ちなかったことが解決し、本当にありがとうございました。
popobot

2020/02/16 02:33

_list..shuffle()..first だと、戻り値がリストになってしまい、firstの結果は取得できないと思います print(_list..shuffle()..first); の実行結果は [one, three, two] のようになります
copp

2020/02/16 02:44

訂正して頂き助かりました。 あやうく変な勘違いをしてしまう所でした。 本当にありがとうございました。
guest

0

そんな感じです!

shuffleはvoidで、破壊的に変更して、戻り値は返さない感じです。

以下のようにカスケード記法は、
破壊的に変更したあとの_listを返してくれてるので、firstが呼べます。

print((_list..shuffle()).first);

3.4だと、voidに対して、firstを読んでるので、エラーになってる感じです〜。

投稿2020/02/15 10:58

kiddayo

総合スコア240

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

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

copp

2020/02/16 02:27

カスケードについて理解することができました。 ご返答、本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問