继续,Dart函数有现象java和js的结合和扩展。如果您学习过java和js,对理解Dart函数很有帮助:
一、Dart函数语法:
返回类型 方法名称(参数1类型 参数1,参数2类型 参数2,...){ 方法体 return 返回值; }如:
int doubleNum(int num){ return num*2; }方法的返回值、参数类型都是可以省略的,比如上面的方法,像下面这样写也可以:
doubleNum(num){ return num*2; }如果函数体就一句话,一个返回值,您也可以写成下面这样:
doubleNum(num) => num*2建议加上返回值、参数类型,这样可以约束方法的调用者对方法的传参和取值,最大限度的避免错误使用方法。
二、函数作用域
Dart中函数可以定义在main方法外,也可以定义在main方法内,也可以嵌套在函数内,比如:
void main(){ print(doubleNum(2)); aaa() { print(doubleNum(2)); bbb(){ print(doubleNum(2)); print("bbbb"); } bbb(); return "aaa"; } print(aaa()); print(aaa()); } int doubleNum(int num){ return num*2; }上面的代码中,doubleNum方法定义在main方法外,它的作用域是全局的, main、aaa、bbb方法都可以调用它。aaa方法定义在main方法中,作用域在main方法中,即在main方法外是不能调用aaa的。bbb方法定义在aaa方法内,在aaa方法外则无法调用,比如想在main方法中调用bbb方法就会报错。
三、传参
1、可选参数
Dart中可以定义可选参数,使用“[]”符号包围的参数即可选参数:
String printUserInfo(String username, [int age]) { if (age != null) { return "姓名:$username---年龄:$age"; } return "姓名:$username---年龄保密";//姓名:张三---年龄保密 } print(printUserInfo('张三'));2、默认参数
Dart也可以定义默认参数,默认参数在调用者不传值的情况下有一个默认值,定义方法如下:
String printUserInfo(String username, [String sex = '男', int age]) { if (age != null) { return "姓名:$username---性别:$sex--年龄:$age"; } return "姓名:$username---性别:$sex--年龄保密"; } print(printUserInfo('张三'));//姓名:张三---性别:男--年龄保密 print(printUserInfo('小李', '女'));//姓名:小李---性别:女--年龄保密 print(printUserInfo('小李', '女', 30));//姓名:小李---性别:女--年龄:303、命名参数
Dart中有命名参数,命名参数在传值时需指定传参的参数名,如果不指定参数名则会报错。
String printUserInfo(String username, {int age, String sex = '男'}) { if (age != null) { return "姓名:$username---性别:$sex--年龄:$age"; } return "姓名:$username---性别:$sex--年龄保密"; } print(printUserInfo('张三', age: 20, sex: '未知'));//姓名:张三---性别:未知--年龄:20 print(printUserInfo('张三', 20, '未知'));//报错4、函数作为参数
Dart同js一样可以将函数作为参数,之前学习的集合遍历中forEach方法的参数即为一个函数。定义函数参数的方法如下:
fn(callback){ callback(); } fn((){ print("此方法为一个参数函数");//此方法为一个参数函数 });四、箭头函数
Dart中也有箭头函数,但是Dart中的箭头函数同js中不同的是,在Dart中箭头函数有且仅有一行方法体,不管加不加{},都不能有第二行方法体,同时方法体语句结尾也不能加分号。如下以集合遍历作为案例演示箭头函数:
List list = ['苹果', '香蕉', '西瓜']; list.forEach((value) { print(value); }); list.forEach((value) => print(value));//匿名函数不加{},后面不能加; list.forEach((value) => {print(value)});//增加{},{}中也不能加;五、匿名函数
Dart中同样可以定义匿名函数,定义方法如下:
var printNum = () { print(123); }; printNum();//123匿名函数也可以作为参数传递给以函数作为参数的函数,比如集合遍历:
list.forEach((value) { print(value); });六、自执行函数
Dart同js一样可以定义自执行函数,定义匿名函数同时调用匿名函数,方法如下:
((int n) { print(n);//12 print('我是自执行方法');//我是自执行方法 })(12);上面的代码中,同时演示了再定义自执行函数的时候可以定义参数并传递参数。
七、闭包
在解释闭包之前需要了解两个概念:
1、全局变量特点: 全局变量常驻内存、全局变量污染全局
var a = 123; void main() { print(a);//123 fn() { a++; print(a); } fn();//124 fn();//125 fn();//126 }2、局部变量的特点: 不常驻内存会被垃圾机制回收、不会污染全局
main() { printInfo() { var myNum = 123; myNum++; print(myNum); } printInfo();//124 printInfo();//124 printInfo();//124 }现在想实现的功能:
1.常驻内存
2.不污染全局
这时候闭包可以解决这个问题,闭包: 函数嵌套函数, 内部函数会调用外部函数的变量或参数, 变量或参数不会被系统回收(不会释放内存)
闭包的写法: 函数嵌套函数,并return 里面的函数,这样就形成了闭包。
main() { fn() { var a = 123; // 不会污染全局 常驻内存 return () { a++; print(a); }; } var b = fn(); b();//124 b();//125 b();//126 }至此,Dart函数介绍完了,您理解了没!?