函数也是对象
既然函数也是对象,那么我们就可以将函数作为参数传递给另一个函数。例如:
void printElement(int element) {
print(element);
}
var list = [1, 2, 3];
// 将 printElement 函数作为参数传递。
list.forEach(printElement);
tips:forEach():可以遍历一个数组或者是一个map
输出:
1
2
3
也可以将函数赋值给一个变量,比如:
temp(dynamic s){
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
return loudify(s);
}
main(){
var c = temp("hello");
print(c);
}
输出:
!!! HELLO !!!
估计有的同学看到这一步该迷惑了,上面代码中的函数为什么没有名字呢?
这就是匿名函数,大多数方法都是有名字的,比如 main() 或 printElement()。你可以创建一个没有名字的方法,称之为 匿名函数。
你可以将匿名方法赋值给一个变量然后使用它,比如将该变量添加到集合或从中删除。
匿名方法看起来与命名方法类似,在括号之间可以定义参数,参数之间用逗号分割。
后面大括号中的内容则为函数体:
([[类型] 参数[, …]]) {
函数体;
};
下面代码定义了只有一个参数 item 且没有参数类型的匿名方法。List 中的每个元素都会调用这个函数,打印元素位置和值的字符串:
var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
print('${list.indexOf(item)}: $item');
});
运行后:
0: apples
1: bananas
2: oranges
在上节我们知道了简写法:
list.forEach((item) => print('${list.indexOf(item)}: $item'));
作用域
变量的作用域在写代码的时候就确定了,大括号内定义的变量只能在大括号内访问,与 Java 类似。
下面是一个嵌套函数中变量在多个作用域中的示例:
bool topLevel = true;
void main() {
var insideMain = true;
void myFunction() {
var insideFunction = true;
void nestedFunction() {
var insideNestedFunction = true;
assert(topLevel);
assert(insideMain);
assert(insideFunction);
assert(insideNestedFunction);
}
}
}
这个好理解。一层一层往外剥就是了。
闭包 即一个函数对象,即使函数对象的调用在它原始作用域之外,依然能够访问在它词法作用域内的变量。
函数可以封闭定义到它作用域内的变量。
//返回一个将 [addBy] 添加到该函数参数的函数。
Function makeAdder(num addBy) {
return (num i) => addBy + i;
}
void main() {
// 生成加 2 的函数。
var add2 = makeAdder(2);
// 生成加 4 的函数。
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
所有的函数都有返回值。没有显示返回语句的函数最后一行默认为执行 return null;。
foo() {}
assert(foo() == null);
结语:
最近在录制视频,到时候也会免费放在公众号中供大家学习交流使用。如果对您有用请关注,如果文中有错也欢迎指正。共同学习,共同进步。请持续关注“计算机自学平台”。