2.6 函数 – 《简单易懂的Dart》
2.6.1 第一类函数
第一类函数数就是Dart中的lambda表达式,只有一条语句.
这种形式的函数我们在2.4.3 for each循环中已经接触过.
第一类函数由2部分组成,分别是参数部分和返回部分.
我们来看一个简单的第一类函数:
(int i) => i+1
其中(int i)是其参数部分,用于接收参数.
i+1是其返回部分,用于决定返回值.
这里定义了一个int类型的变量i,并将i+1的结果返回给函数的调用者.
由于第一类函数没有函数名,我们也可以称之为匿名函数.
下面是一个简单的调用上面代码的例子:
void main(){
print(((int i)=>i+1)(100));
}
输出结果为101,来分析一下它的执行顺序.
首先,((int i) => i+1)使它成为了一个第一类函数,最外层的()将其作为一个对象(这里是函数对象)来对待,后面(100)则是将100作为参数传进函数.
然后,值100进入了函数,100是一个整型值,它通过了int i的类型检查,根据表达式i+1将执行100+1的操作.
最后,100+1=101作为返回值返回,print受到参数并打印出101.
2.6.2 标准函数
标准函数是我们喜闻乐见的C类语言照搬版本.
格式如下:
返回值类型 函数名(参数表){
函数体
return 返回值
}
上面那个第一类函数的例子也可以写成标准函数:
void main(){
int plus1(int i){
return i+1;
}
print(plus1(100));
}
这里需要注意的是,返回值与其返回值类型必须一致,否则将会出错.
但是这样又有了返回值的局限性,Dart就这么的不好用吗?
当然不是,其实标准函数的返回值类型是可以省略的!
void main(){
plus1(int i){
return i+1;
}
print(plus1(100));
}
因为这个特性,所以这段代码可以正常执行.
2.6.3 可省参数
Dart支持可省参数,增强了一定的灵活性.
可省参数需要遵循2个规范:可省参数位于函数表的最后,可省参数必须被包括在[]中.
我们将上面的plus1函数加以强化,使它在接收到第二个参数时可以变为两个参数相加.
void main(){
plus1(int i,[int j]){
if(j!=null){
return i+j;
}else{
return i+1;
}
}
print(plus1(100));
print(plus1(100,200));
}
输出结果为
101
300
如果可省参数被省略,则其值为null,我们可以依靠这个特性编写if(j!=null)来判断参数是否省略.
由于return后不会继续执行下面的代码,这段代码还可以写成这样:
void main(){
plus1(int i,[int j]){
if(j!=null){
return i+j;
}
return i+1;
}
print(plus1(100));
print(plus1(100,200));
}
2.6.4 参数默认值
在上一节学习了可省参数,这里再学习一下可省参数的默认值写法.
给参数设置默认值非常简单,就像定义一个变量并给它赋值一样容易.
上面的例子中j如果不存在则将执行i+1的操作,下面我们把j的默认值设置为1.
这样在参数j被省略时执行i+1,参数j存在时执行i+j.
代码是这样的:
void main(){
plus1(int i,[int j=1]){
return i+j;
}
print(plus1(100));
print(plus1(100,200));
}
plus1(100)时由于参数j被省略,其默认值1使得i+j=i+1=100+1=101.
plus1(100,200)时由于参数j未被省略,其默认值不生效,j=200,使得i+j=i+200=100+200=300.
2.6.5 无类型参数
干脆连参数的类型都不要定义了吧,这多方便啊!
void main(){
plus1(i,[j=1]){
return i+j;
}
print(plus1(100));
print(plus1(100,200));
}
Dart:什么?你说我有点像JavaScript?
2.6.6 函数对象
上面或多或少提到了——函数其实是个对象.
函数对象的类型为Function类型.
所以它是可以被赋值的.像这样:
void main(){
plus1(i,[j=1]){
return i+j;
}
Function plus2=plus1;
print(plus2(100));
print(plus2(100,200));
}
Function类型变量plus2初始化时给他plus1,此时plus2有了和plus1同样的对象.
返朴归真一下,现在我们把plus1还原成第一类函数吧.
void main(){
Function plus1=(i,[j=1])=>i+j;
print(plus1(100));
print(plus1(100,200));
}
是不是有一种很高级的感觉?第一类函数同样支持标准函数的种种特性.
我们索性连Function也换成var怎么样?
void main(){
var plus1=(i,[j=1])=>i+j;
print(plus1(100));
print(plus1(100,200));
}
只需要添加几个字符,原来的那个第一类函数就增加了新功能,并且还进行了命名!