一、Dart方法
Dart中,方法也是对象并且是Function
类的实例,因此,方法可以赋值给变量,也可以当做其他方法的参数,还可以是把Dart类
的实例当做方法来调用,示例如:
String greet(String name) {
return 'Hello, $name';
}
对于公开的API,推荐使用静态类型,不过这不代表静态类型是强制的,也可以不适用静态类型,而使用自动类型推断:
greet(name) {
return 'Hello, $name';
}
1、箭头语法
对于只有一个表达式的方法,还可以使用缩写的语法,如下:
bool greaterThanTen(n) => n > 10;
// 它相当于:
bool greaterThanTen(n) {
return n > 10;
}
也就是说,缩写的语法=> expr
相当于{ return expr; }
缩写语法中,不能使用
语句
(if
、else
、while
之类),但是可以使用表达式与条件表达式
2、必选参数与可选参数
方法的参数类型分为必选参数
和可选参数
,必选参数必须在参数列表的最前面,而可选参数则需要放在必选参数的后面
1)命名参数
使用{ param1, param2, ... }
来指定命名参数:
void greet({ String action, String what }) {
print('$action $what');
}
// 调用方法如下:
greet(what: 'Hello', action: 'say');
2)可选参数
可选参数需要将放置于[]
中,如下:
void greet(String from, String msg, [String device]) {
print('$from says $msg');
if (device != null) {
print('via $device');
}
}
// 调用方法如下:
greet('Ruphi', 'hello'); // 输出: Ruphi says Hello
greet('Ruphi', 'hello', 'iPhone 8 Plus');
/*
输出:
Ruphi says Hello
via iPhone 8 Plus
*/
3)默认参数
定义方法时,可以用=
来指定参数的默认值,但是默认值只能是编译时常量
,如果没有提供默认值,则默认值为null
,如:
void greet({ String from = '?', String msg = 'Hello' }) {
print('$from says $msg');
}
greet();
而对于位置参数
(相对于命名参数
)而言,则需要这么设置默认值:
void greet(String from, String msg, [String device = 'iPhone']) {
print('$from says $msg');
if (device != null) {
print('via $device');
}
}
greet('Ruphi', 'Hello');
3、函数入口
每个应用都要一个顶级的main()
入口才能得到执行,main()
的返回值是void
,并且有个可选的List<String>
参数(它提供看来自控制台的输入,可以使用args library
来定义和解析命令行输入的参数数据):
void main(List<String> arguments) {
print(arguments);
}
4、一等方法对象
可以将方法当做参数传递给另外一个方法,如:
printElement(element) {
print(element);
}
var list = [1, 2, 3];
list.forEach(printElement);
方法也可以赋值给一个变量,如:
var showList = (list) => list.forEach((i) => print(i));
5、匿名方法
没有方法名的方法称为匿名方法
(又称为lambda
或者closure
),匿名方法的语法如下:
([[Type] param1[, ...]]) {
codeBlock;
};
示例:
var list = ['apple', 'orange', 'grape', 'banana'];
list.forEach((item) {
print(list.indexOf(item).toString() + ': ' + item);
});
如果只包含一个语句,则可以使用=>
语法,如以上可以改为:
list.forEach((item) => print(list.indexOf(item).toString() + ': ' + item));
6、词法作用域(静态作用域)
Dart
变量的作用域在写代码的时候就已经确定了,因此,大括号里定义的变量就只能在大括号里访问,如:
var topLevel = true;
main() {
var insideMain = true;
myFunction() {
var insideFunction = true;
nestedFunction() {
var insideNestedFunction = true;
}
}
}
7、词法闭包
一个闭包
是一个方法对象,不论该对象在何处被调用,该对象都能访问自己作用域内的变量(即捕获了的变量),如下:
Function uid() {
int id = 0;
return () => id++;
}
main() {
var uidGenerator = uid();
print(uidGenerator());
print(uidGenerator());
print(uidGenerator());
}
/*
输出:
0
1
2
*/
8、函数相等
判断函数相等的示例如下:
foo() {} // 顶级函数
class A {
static void bar() {} // 静态方法
void baz() {} // 实例方法
}
main() {
var x;
// 比较顶级方法
x = foo;
assert(foo == x); // 通过
// 比较静态方法
x = A.bar;
assert(A.bar == x); // 通过
// 比较实例方法
var v = new A(); // A的实例 #1
var w = new A(); // A的实例 #2
var y = w;
x = w.baz;
// 因为 y.baz 和 x 都是指向实例#2的baz方法,因此它们是相等的
assert(y.baz == x); // 通过
// v.baz指向的是#1的baz方法,w.baz指向的是#2的baz方法,因此它们不相等
assert(v.baz != w.baz); // 通过
}
9、返回值
所有的函数都返回一个值,如果没有指定返回值,则默认函数的最后一个语句是return null;
,也就是说没有指定返回值的情况下,返回值是null