28

如飞镖文章中所述:

“..”语法调用方法(或 setter 或 getter)但丢弃结果,并返回原始接收器。

所以我认为这会起作用:

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

这给了我无法调用的.addAll错误null

所以显然.在. _ _ _...addAll.clear()

我现在想我有两种可能性来写这个:

  1. myList..clear()..addAll(otherList);
  2. (myList..clear()).addAll(otherList);(如果我想得到.addAll().

这个对吗?如果是,为什么决定给予.优先权?这似乎非常违反直觉。是否要避免这样的语法:myList(..clear().useResultOfClear()).addAll(otherList);

4

5 回答 5

40

正如官方 Dart 语言文章Method Cascades in Dart中所指出的:

“..”语法调用方法(或 setter 或 getter)但丢弃结果,并返回原始接收器

简而言之,方法级联为方法调用的接收者可能不得不重复的情况提供了语法糖。

以下是基于/复制先前引用的文章的示例。欲了解更多信息,请阅读它

add()例子

在想要将多个元素添加到列表的场景中,传统方式是执行多个分配:

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

虽然您不能做类似myList.add("item1").add("item1")….add("itemN");的事情,因为add()does not 方法返回myList对象而是 avoid,但您可以使用级联运算符,因为它会丢弃结果并返回原始接收者myList

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

另一个例子

所以不要写:

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

一个人可以写

getAddress()
 ..setStreet(“Elm”, “13a”)
 ..city = “Carthage”
 ..state = “Eurasia”
 ..zip(66666, extended: 6666);
于 2014-02-16T10:46:37.543 回答
24

您可以阅读 Gilad Bracha 中的文章:Dart 中的方法级联。在它的结尾,你会看到很多例子。

另请参阅Lasse Nielsen 关于运算符优先级的答案

它有助于将“..”视为不是真正的运算符,而更像是一个范围构造(如括号)。它创建一个从“..”到下一个“..”或第一个其他范围分隔符(“;”、“)”、“}”或类似)的新范围。

基本上a..b().c()是一样的(t){t.b().c(); return t;}(a)

于 2013-06-10T14:24:06.767 回答
3

A..B().C()表示调用B()A然后C()根据 的返回值调用A.B()

A..B().C()..D().E()意思是调用B()A然后C()根据返回值调用A.B(),假设是A_B,然后调用D()A_BA_B.D()假设返回值是A_B_D,然后最后做A_B_D.E()

于 2019-05-07T14:53:00.730 回答
1

要对同一对象执行一系列操作,请使用 cascades (..)。我们都见过这样的表达:

myObject.someMethod()

它调用someMethod()on myObject,表达式的结果是 someMethod() 的返回值。

这是具有级联的相同表达式:

myObject..someMethod()

尽管它仍然调用someMethod()on myObject,但表达式的结果不是返回值——它是对myObject!的引用 使用级联,您可以将原本需要单独语句的操作链接在一起。例如,考虑以下代码:

var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));

使用级联,代码变得更短,并且您不需要button变量:

querySelector('#confirm')
..text = 'Confirm'
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));

代码示例

使用级联创建单个语句,将 a 的anIntaStringaList属性设置BigObject为 1、String![3.0](分别),然后调用allDone().

class BigObject {
  int anInt = 0;
  String aString = '';
  List<double> aList = [];
  bool _done = false;
  
  void allDone() {
    _done = true;
  }
}

BigObject fillBigObject(BigObject obj) {
  return obj
    ..anInt = 1
    ..aString = 'String!'
    ..aList.add(3)
    ..allDone();
}
于 2021-01-16T03:13:03.247 回答
1

出自:傅诚的《Flutter食谱》:

Dart 有一个特殊的级联运算符 (..),它允许我们对同一个对象进行一系列操作。要在其他编程语言中对同一对象进行链式操作,我们通常需要创建一个流畅的 API,其中每个方法都返回当前对象。Dart 中的级联运算符使这个要求变得不必要。即使方法不返回当前对象,它们仍然可以被链接。级联运算符还支持现场访问。

class User {
  String name, email;
  Address address;
  void sayHi() => print('hi, $name');
}

class Address {
  String street, suburb, zipCode;
  void log() => print('Address: $street');
}

void main() {
  User()
   ..name = 'Alex'
   ..email = 'alex@example.org'
   ..address = (Address()
     ..street = 'my street'
     ..suburb = 'my suburb'
     ..zipCode = '1000'
     ..log())
   ..sayHi();
}


 
于 2021-12-27T09:17:47.867 回答