闭包
函数可以定义在表达式的内部。它们被称为函数字面量,也被称为闭包或者匿名函数。与函数声明不同,闭包没有函数名称。虽然如此,与其他函数一样,它们也有参数列表与函数体。
(x) => x;
(x) { return x; }
(x, [step = 1]) => x + step;
(a, b) => a + b;
单看这些例子,可能不会马上明白闭包有多大的用处。它们看起来就像是没有名称的函数声明。而真正的好处则来自于将它们作为大型表达式的一部分。
考虑一个列表元素求和的问题。我们可以使用for循环来实现这一点,但那时比较原始的实现方式。一个有经验的Dart开发者会这样去实现:
Dart中的列表及其他很多类型都定义了reduce()方法。任意实现了Iterable接口的类型应该都有一个可运行的内置函数reduce()。具体如何使用reduce你可以查询官方API的使用。我们在这里当然也可以不使用闭包来实现:
sum(nums){ // 不好的代码风格
plus(a, b) => a + b;
nums.reduce(plus);
}
以上代码稍显啰嗦并需要我们明明一个额外的函数。在执行加法的情况下,函数的名称还是显而易见的,但对下面这样的函数进行命名就变得很繁重:
country.cities.where((city) => city.population > 1000000);
这个函数可以找出所有country中人口数量大于一百万的城市。这段代码使用了where()方法,它也来自于Iterable,接受一个函数作为参数。在这种情况下,where()的参数必须是一个一元断言函数,而它将返回那些断言为真的元素。