简介:
Dart是一种真正的面向对象语言,所以函数也是对象,并且有一个类型Function。这意味着函数可以赋值给变量,也可以作为参数传递给其他函数。您还可以调用Dart类的实例,就像它是一个函数一样。有关详细信息,请参见Callable类。
要点总结:
- 函数也是对象,且函数有对应的类Function;
- 函数可以作为变量,也可作为函数的参数;
- 类的实例也可以像函数一样调用,见可调用类;
函数的声明和实现:
函数实现:
returnType functionName(param1, param12, ...) {
code
return type;
}
一些注意点:
- 返回类型可以省略,但是为了可读性一般不会省略;
- 当返回类型为
void
时,reutrn
语句为return null;
可以省略; - 箭头语法
=> expr
是{return expr;}
的省略写法,且=>
和;
之间只有表达式不能出现语句;
// 例子
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
// 省略返回值
isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
// 箭头语法
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
函数参数:
一个函数可以有任意数量的所需位置参数。后面可以跟命名参数,也可以跟可选的位置参数(但不能同时跟)。
参数分类
类别 | 中文 | 描述 |
---|---|---|
No Named parameters | 匿名参数 | 调用函数时不用参数的名字 |
Named parameters | 命名参数 | 在{} 内,调用函数时需要参数的名字 |
Optional Named parameters | 可选命名命名参数 | 调用函数时该参数不是必传参数 |
required parameters | 必传参数 | 调用函数时必传该参数 |
Optional positional parameters | 可选位置参数 | 应用程序的入口 |
注意点:
-
{}
内必传参数需要加required
关键字; -
{}
内可选不为空的参数,必须提供默认值; -
{}
内可选为空的参数,需要?
允许参数为null
; -
[]
内可选位置参数,基本上没用。
// 匿名必传参数
void showName(String name) {
print(name);
}
// 调用
showName("Luck");
// 命名参数:name为命名必传参数;age和sex是可选命名参数,不能为空,需提供默认值;hadCar是可选默认参数,可以为null
void show({ required String name, int age = 0, bool sex = true, bool? hadCar}) {
print('name = $name, age = $age, sex = ${sex ? 'man' : 'woman'}');
if (hadCar == true) {
print('$name had car');
}
}
// 调用
show(name: "Lucy", age: 12, sex: true, hadCar: true);
函数分类:
函数分类:
类别 | 中文 | 描述 |
---|---|---|
main() | 主函数或者入口函数 | 应用程序的入口 |
Global function | 全局函数 | main之外定义的函数,或是直接在main函数中定义的函数都是全局函数,可以可以全局调用 |
Local function | 局部函数 | 相对全局函数定义,不是全局函数的,都是局部函数 |
instance function | 实例函数 | 类实例调用的函数 |
class/static function | 类函数或者静态函数 | 类名直接调用的函数 |
Anonymous function | 匿名函数 | 没有名字的函数,也被称为(java中)lambda 或者 (swift中)closure 闭包 |
main()函数:
每个应用程序都必须有一个顶级的main()函数,它作为应用程序的入口点。main()函数返回void,并有一个可选的List<String>参数作为参数。
// main之外定义的全局函数
int globalOutMain() {
return 123;
}
void main(){
// main里的全局函数
int globalInMain(){
return 123;
}
// 调用
globalOutMain();
globalInMain();
}
// 实例方法和类方法
class Person {
static String className = 'Person';
late final String name;
void show() {
print(name);
}
static void showClassName() {
print(className);
}
}
// 调用
final persion = Person();
persion.name = 'jack';
persion.age = 16;
persion.show();
Person.showClassName();
匿名函数 :
匿名函数的声明:
// 第一种声明
(param1, param2, ...) {
code;
return type;
}
// 第二种声明:声明一个匿名函数,并赋值给变量functionName
functionName(param1, param2, ...) {
code;
return type;
}
// 第二种声明等价于
var functionName = (param1, param2, ...) {
code;
return type;
};
注意点:
- 匿名函数可以赋值给变量;
- 其实匿名函数可以有名字的,即为赋值的变量;
- 匿名函数通过赋值的变量进行调用,这就是所说的函数表达式;
- 匿名函数可以自执行;
- 匿名函数哦一些方法的回调函数,即匿名函数可以作为函数的参数。
// 声明一个匿名函数,并赋值给变量function1
function1(int a, int b) {
return (a + b);
}
// 将匿名函数赋值给一个变量
var fVar = function1;
// 匿名函数调用
print(function1(2, 3));
print(fVar(2, 3));
// 匿名函数自执行
() {
print('匿名函数自执行');
} ();
const list = ['apples', 'bananas', 'oranges'];
// 匿名函数作为回调函数,即作为函数的参数
list.forEach((item) {
print('${list.indexOf(item)}: $item');
});
变量作用域和变量闭包:
Dart是一种词法作用域限定的语言,这意味着变量的范围是静态地确定的,简单地由代码的布局决定。
闭包即匿名函数是一个函数对象,它可以访问其词法作用域内的变量,即使该函数是在其原始作用域之外使用的。
-
{}
外的变量或常量可以在{}
内使用; -
{}
内的变量或常量不可以在{}
外使用;
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);
}
}
}
// 返回值是闭包函数
Function makeAdder(int addBy) {
return (int i) => addBy + i;
}
// 调用
var add2 = makeAdder(2);
var add4 = makeAdder(4);
print(add2(1));
print(add4(1));
函数等价判断 :
下面是一个测试顶级函数(全局函数)、静态方法和实例方法是否相等的例子:
可调用类:
可调用类即类的实例可以像函数一样进行调用的类。怎样才能让类的实例像函数一样进行调用呢?很简单只需要在类中实现一个call()
函数。如下:
class WannabeFunction {
// String call(String a, String b, String c) => '$a $b $c!';
// String call() => '123';
int call(int a) => (a + 1);
}
var wf = WannabeFunction();
// print(wf('Hi', 'there,', 'gang'));
// print(wf());
print(wf(1));
网友评论