作者 | 弗拉德
起源 | 弗拉德(公众号:fulade_me)
函数
Dart 同样也是一种面向对象的语音。所以即使函数也是一个对象。类型为
Function
,这意味着函数可做作为变量,也也能够作为函数的参数。
上面是定义一个函数的例子:
isEmpty(List aList) {return aList.length == 0;}
为了标准其实咱们须要在函数的头部申明一下返回值类型,当然如果不申明也能够运行,
bool isEmpty(List aList) {return aList.length == 0;}
如果函数体内只蕴含一个表达式,你能够应用简写语法:
bool isEmpty(List aList) => aList.length == 0;
=>
表白的 是 {return 表达式;}
的简写,有时 =>
也称之为 胖箭头语法。
参数
函数能够有两种模式的参数:必选参数 和 可选参数。必选参数定义在参数列表后面,可选参数肯定是定义在必要参数前面。
可选的命名参数
当你调用函数时,能够应用 参数名: 参数值 的模式来指定命名参数。例如:
enableFlags(bold: true, hidden: false);
已命名的参数是可选参数了,除非他们被特地标记为 required
。
定义函数时,应用 {param1, param2, …}
来指定命名参数:
/// 设置 [bold] 和 [hidden] 标识……
void enableFlags({bool bold, bool hidden}) {...}
尽管命名参数是可选参数的一种类型,然而你依然能够应用 @required
注解来标识一个命名参数是必须的参数,此时调用者则必须为该参数提供一个值。例如:
const Scrollbar({Key key, @required Widget child})
如果调用者想要通过 Scrollbar
的构造函数结构一个 Scrollbar
对象而不提供 child 参数,则会导致编译谬误。
可选参数
应用 []
将一系列参数包裹起来作为可选参数:
strings(String s1, String s2, [String s3]) {
var result = '$s1 and $s2';
if (s3 != null) {result = '$result and $s3';}
print(result);
}
上面是不应用可选参数调用上述函数的示例:
strings("s1", "s2");
s1 and s2
上面是应用可选参数调用上述函数的示例:
strings("s1", "s2", "s3");
s1 and s2 and s3
默认参数值
咱们能够用 =
为函数的命名参数和可选参数定义默认值,默认值必须为编译时常量,没有指定默认值的状况下默认值为 null
。
上面是设置可选参数默认值示例:
/// 设置 [bold] 和 [hidden] 标识……
void enableFlags({bool bold = false, bool hidden = false}) {...}
// bold 的值将为 true;而 hidden 将为 false。enableFlags(bold: true);
下一个示例 默认值:
strings(String s1, String s2, [String s3 = 'this is s3', String s4]) {
var result = '$s1 and $s2';
if (s3 != null) {result = '$result and $s3';}
if (s4 != null) {result = '$result and $s4';}
print(result);
}
strings("s1", "s2");
s1 and s2 and this is s3
main() 函数
每个 Dart
程序都必须有一个 main()
顶级函数作为程序的入口,main()
函数返回值为 void
。
上面是一个 Flutter 利用的 main()
函数示例:
void main() {runApp(MyApp());
}
函数作为参数
能够将函数作为参数传递给另一个函数。例如:
void printElement(int element) {print(element);
}
// 将 printElement 函数作为参数传递。var list = [1, 2, 3];
list.forEach(printElement);
你也能够将函数赋值给一个变量,比方:
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
var result = loudify('hello');
print(result);
匿名函数
大多数办法都是有名字的,比方
main()
或printElement()
。你能够创立一个没有名字的办法,称之为 匿名函数,其实匿名函数很常见,也有不同的叫法,在 C ++ 外面叫 Lambda 表达式,在 Objective- C 叫 Block 闭包。你能够将匿名办法赋值给一个变量而后应用它。
匿名办法看起来与命名函数 h 相似,在括号之间能够定义参数,参数之间用逗号宰割。
前面大括号中的内容则为函数体:
([[类型] 参数[, …]]) {函数体;};
上面代码定义了只有一个参数 item
且没有参数类型的匿名办法。List
中的每个元素都会调用这个函数,打印元素地位和值的字符串:
var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {print('${list.indexOf(item)}: $item');
});
如果函数体内只有一行语句,你能够应用胖箭头缩写法。上面代码的运行后果,与下面代码的运行后果是统一的。
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);
}
}
}
留神 nestedFunction()
函数能够拜访包含顶层变量在内的所有的变量。
返回值
所有的函数都有返回值。没有显示返回语句的函数最初一行默认为执行 return null
;。
foo() {}
assert(foo() == null);
本文所有代码都已上传到 Github