首页 > 建站教程 > dart >  Dart函数详解正文

Dart函数详解

先来个函数与美女压压惊:

dart函数

继续,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));//姓名:小李---性别:女--年龄:30
3、命名参数
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函数介绍完了,您理解了没!?