前面的章节有提到过,在 Dart 中,函数也是一个对象,它的类型是 Function。
它可以被赋值给变量,可以被作为参数传递。
声明一个函数
这是个常规的函数声明:
bool isNoble(int atomicNumber) {
return atomicNumber != null;
}
如果一个函数没有显示声明返回值,Dart 会自动推导它的返回值类型。
void main() { bool b = isNoble(2); print(b); } isNoble(int atomicNumber) { return atomicNumber != null; } >>> true
如果一个函数没有显示的
return
,那么它默认会返回 null。fun(){} assert(fun() == null)
如果一个函数只有一句表达式,可以使用简写:
bool isNoble(int atomicNumber) => atomicNumber != null; isNoble(int atomicNumber) => atomicNumber != null;
可选命名参数
通过 {}
符号,可以用于指定函数参数的名称。
void enableFlags({bool bold = false, bool hidden = false, @required String content}) {
// ...
}
可以看到,Dart 支持我们给参数设置默认值。
调用:
enableFlags(bold: true, content: 'required');
enableFlags(bold: true, hidden: false, content: 'required');
使用 @required
注释的参数,表示必要的参数,在调用的时候你不能遗漏它。
这样的书写形式也是被允许的,不使用 :
:
void doStuff(
{List<int> list = const [1, 2, 3],
Map<String, String> gifts = const {
'first': 'paper',
'second': 'cotton',
'third': 'leather'
}}) {
print('list: $list');
print('gifts: $gifts');
}
可选位置参数
通过 []
符号,可以指定该位置的参数是可选的:
String say(String from, String msg,
[String device = 'carrier pigeon', String mood]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
if (mood != null) {
result = '$result (in a $mood mood)';
}
return result;
}
assert(say('Bob', 'Howdy') ==
'Bob says Howdy with a carrier pigeon');
其中参数 device
和 mood
的位置的参数就是可选的,且 device
有默认值。
函数作为变量
正如前面所说,Dart 中的函数是一个 Function 类型的对象,因此它可以被赋值给一个变量。
var say= (str){
print(str);
};
say("hi world");
函数作为入参
函数作为一个对象,它当然也可以被作为参数传递:
void execute(var callback){
callback();
}
execute(()=>print("xxx"))
函数闭包
Dart 函数的特性,使得它很容易实现闭包:
// 返回一个函数对象
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);
}
从这个例子中,可以感受到闭包的强大,它相当于定义了一个动态可配置的函数对象。
typedef 关键字
Dart 提供了 typedef
关键字来定义一种函数格式(具有严格的格式检查),比如:
typedef int Compare(Object a, Object b);
那么,这种格式的函数就被定义成了 Compare 类型。实际上和类的定义是类似的概念。
看看这个例子:
Compare test = (Object a, Object b){
return 0;
}
形如此类的函数,就是 Compare 类型的函数。
当你打算把一个函数赋值给 Compare 类型的变量时,它会严格检查 函数的参数类型 和 返回值类型 是否和 Compare 类型函数 完全对应,不对应的话,编译就会报错。