How do method cascades work exactly in dart?

2019-04-21 14:46发布

As stated in the dart article:

The ".." syntax invokes a method (or setter or getter) but discards the result, and returns the original receiver instead.

So I assumed that this would work:

myList..clear().addAll(otherList);

which gave me the error that I can't call .addAll on null.

So apparently . precedes .. so that .addAll has been invoked on the result of .clear().

I figure now that I have two possibilities to write this:

  1. myList..clear()..addAll(otherList);
  2. (myList..clear()).addAll(otherList); (If I wanted to get the result of .addAll().

Is this correct? If yes, why the decision to give . precedence? It seems very counterintuitive. Is it to avoid syntax like this: myList(..clear().useResultOfClear()).addAll(otherList);?

2条回答
做自己的国王
2楼-- · 2019-04-21 15:41

As pointed in the official Dart language article Method Cascades in Dart:

The ".." syntax invokes a method (or setter or getter) but discards the result, and returns the original receiver instead.

In brief, method cascades provide a syntactic sugar for situations where the receiver of a method invocation might otherwise have to be repeated.

Below are example based/copied from the previously cited article. For further information, go read it.

add() example

In the scenario where one want to add multiple elements to a list, the legacy-way is to do multiple assignements :

myList.add("item1");
myList.add("item2");
// add again and again…
myList.add("itemN");

While you can't do something like myList.add("item1").add("item1")….add("itemN"); as the add() does not method return the myList object but a void, you can use the cascading operator instead as it discards the result, and returns the original receiver myList :

myList..add("item1")..add("item2")…..add("itemN");
myList.add("item1").add("item2")….add("itemN");

Another example

So Instead of writing:

var address = getAddress();
address.setStreet(“Elm”, “13a”);
address.city = “Carthage”;
address.state = “Eurasia”
address.zip(66666, extended: 6666);

One may write

getAddress()
 ..setStreet(“Elm”, “13a”)
 ..city = “Carthage”
 ..state = “Eurasia”
 ..zip(66666, extended: 6666);

Further reading

If you want to know more about cascading method, I wrote an article by adding information that goes behind the scope of this question.

查看更多
爷、活的狠高调
3楼-- · 2019-04-21 15:45

You can read the article from Gilad Bracha : Method Cascades in Dart. At its ends, you will see many examples.

See also this answer of Lasse Nielsen about operator precedence :

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)

查看更多
登录 后发表回答