0
点赞
收藏
分享

微信扫一扫

第126期:Dart基础知识(函数)

Functions 函数

Dart是一种面向对象语言,所以即使函数也是对象,也有一个类型Function。这意味着函数可以分配给变量或作为参数传递给其他函数。我们还可以像调用函数一样调用Dart类的实例。

bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}

尽管Dart建议为公共API添加类型注释,但如果省略类型,该函数仍然有效:

isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}

和JS类似,如果函数只有一个表达式,我们可以使用短语法​​箭头函数​​。

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

Params 参数

函数可以具有任意数量的参数。这些参数后面可以是命名参数,也可以是可选的位置参数(但不能同时)。

​一些API,尤其是Flutter小部件构造函数只使用具名参数​

具名参数

定义函数是指定具体的参数,具名参数是可选的

/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool? bold, bool? hidden}) {...}

调用函数时,可以使用paramName:value指定命名参数。例如:

enableFlags(bold: true, hidden: false);

虽然具名参数是可选的,我们可以用​​require​​来指定这个参数是必须的:

const Scrollbar({super.key, required Widget child});

当我们将参数用​​[]​​标记为可选参数:

String say(String from, String msg, [String? device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}

然后调用时,可以不带上可选参数:

assert(say('Bob', 'Howdy') == 'Bob says Howdy');

也可以带上可选参数:

assert(say('Bob', 'Howdy', 'smoke signal') ==
'Bob says Howdy with a smoke signal');

参数默认值

我们可以使用​​=​​​来定义函数的默认值,默认值必须是编译时的常量,如果参数没有默认值,则默认为​​null​

/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool bold = false, bool hidden = false}) {...}

// bold will be true; hidden will be false.
enableFlags(bold: true);

位置参数示例:

String say(String from, String msg, [String device = 'carrier pigeon']) {
var result = '$from says $msg with a $device';
return result;
}

assert(say('Bob', 'Howdy') == 'Bob says Howdy with a carrier pigeon');

当然,我们也可以指定LIST,MAP的默认值:

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');
}

Main() 函数

所有的应用程序都必须有一个顶层函数​​main()​​。

main()函数没有返回值,表示的是程序的开始。

void main() {
print('Hello, World!');
}

匿名函数

大多数函数都是具名的,例如main()或printElement()。我们也可以创建一个名为匿名函数的无名函数,有时也可以创建lambda或闭包。我们可以将匿名函数分配给变量,比如我们可以在集合中进行添加或删除操作。

匿名函数看起来类似于具名函数,括号之间用逗号和可选类型注释分隔零个或多个参数。

const list = ['apples', 'bananas', 'oranges'];
list.map((item) {
return item.toUpperCase();
}).forEach((item) {
print('$item: ${item.length}');
});

这里的:

(item) {
print('$item: ${item.length}');
}

就是匿名函数。

Lexical scope 词域

在JS中,我们通常称为作用域。

下面的例子可以简单看下,理解一下就行了。

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);
}
}
}

Lexical closures 闭包

闭包是一个函数对象,它可以访问其词法范围内的变量,即使函数在其原始范围外使用。

/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(int addBy) {
return (int 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实际上返回了一个函数,所以变量add2包含的是一个函数的引用,然后才调用的add2,add4也一样。

Return Values 返回值

所有函数都返回一个值。如果未指定返回值,则语句返回null;隐式附加到函数体。

foo() {}

assert(foo() == null);

举报

相关推荐

0 条评论