函数也是对象,类型是 Function。
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
如果忽略了参数类型,函数仍然可以正常运行
isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
只有一个表达式的函数,可以简写,类似 Kotlin。=>
后跟着一条表达式,不能是语句,比如 if 语句。
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
函数都有返回值,如果没有指定返回值,则隐式返回 null。
函数本身可以作为参数,返回值,赋值给变量。
可选参数
可选参数可以是位置参数,也可以是命名参数,但不能两者都是。
可选命名参数
定义参数时用 {}
括起来。如
void enableFlags({bool bold, bool hidden}) {...}
// 几种调用方法都可以
enableFlags(bold: true);
enableFlags(hidden: false);
enableFlags(bold: true, hidden: false);
enableFlags(hidden: false, bold: true);
如果要在可选命名参数中注释一个参数,使用 @required
说明它是一个必传的参数。
void enableFlags({bool bold, @required bool hidden}) {...}
enableFlags(bold: true); // 失败,必须有 hidden
Required 在元包中被定义。或者直接使用 import package:meta/meta.dart
导入或者导入其他包含 meta 导出的包,例如 Flutter 的包 Flutter /material.dart
。
可选位置参数
用 []
包装参数。
String say([String device, int i]) {...}
// 如果有参数,第一个必须是 String 类型
say();
say('Bob');
say('Bob', 3);
默认参数值
void enableFlags({bool bold = false, bool hidden = false}) {...}
// bold will be true; hidden will be false.
enableFlags(bold: true);
String say([String device, int i=3]) {...}
say('Bob');
匿名函数
或叫 lambda 函数,或叫闭包函数,形如
([[Type] param1[, …]]) {
codeBlock;
};
例如
var list = ['apples', 'bananas', 'oranges'];
// forEach 的参数就是一个匿名函数
list.forEach((item) {
print('${list.indexOf(item)}: $item');
});
闭包
Function makeAdder(num addBy) {
return (num i) => addBy + i;
}
void main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
makeAdder 返回一个函数,退出 makeAdder 函数后,返回的函数持有局部变量 addBy 的值,就是闭包。
typedef
class SortedCollection {
Function compare;
// 参数是一个函数
SortedCollection(int f(Object a, Object b)) {
// 当把函数赋值给 compare 时,f 的类型就丟了,compare 不知道它的参数列表,不知道它的返回值
compare = f;
}
}
int sort(Object a, Object b) => 0;
void main() {
SortedCollection coll = SortedCollection(sort);
// 只能知道 compare 是 Function,具体的函数签名就不知道了
assert(coll.compare is Function);
}
// 使用 typedef 给函数起个别名,这样 Compare 类型就知道了
typedef Compare = int Function(Object a, Object b);
class SortedCollection {
Compare compare;
SortedCollection(this.compare);
}
int sort(Object a, Object b) => 0;
void main() {
SortedCollection coll = SortedCollection(sort);
assert(coll.compare is Function);
assert(coll.compare is Compare);
}
因为 typedef 仅仅是别名,所以它们提供了一种检查任何函数类型的方法。
typedef Compare<T> = int Function(T a, T b);
int sort(int a, int b) => a - b;
void main() {
assert(sort is Compare<int>); // True!
}
网友评论