当前位置: 代码迷 >> 综合 >> Dart学习笔记七:函数详解
  详细解决方案

Dart学习笔记七:函数详解

热度:37   发布时间:2024-02-20 01:32:50.0

前言

今天学习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;
}

但是建议加上返回值、参数类型,这样可以约束方法的调用者对方法的传参和取值,最大限度的避免错误使用方法。

函数作用域

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方法就会报错。

函数传参

可选参数

Dart中可以定义可选参数,使用“[]”符号包围的参数即可选参数:

String printUserInfo(String username, [int age]) {if (age != null) {return "姓名:$username---年龄:$age";}return "姓名:$username---年龄保密";//姓名:张三---年龄保密
}print(printUserInfo('张三'));

默认参数 

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

命名参数 

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, '未知'));//报错

函数作为参数

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);//12print('我是自执行方法');//我是自执行方法
})(12);

上面的代码中,同时演示了再定义自执行函数的时候可以定义参数并传递参数。

闭包

在解释闭包之前需要了解两个概念:

1、全局变量特点:    全局变量常驻内存、全局变量污染全局

var a = 123;void main() {print(a);//123fn() {a++;print(a);}fn();//124fn();//125fn();//126
}

2、局部变量的特点:  不常驻内存会被垃圾机制回收、不会污染全局

main() {printInfo() {var myNum = 123;myNum++;print(myNum);}printInfo();//124printInfo();//124printInfo();//124
}

现在想实现的功能:

1.常驻内存       

2.不污染全局  

这时候闭包可以解决这个问题,闭包: 函数嵌套函数, 内部函数会调用外部函数的变量或参数, 变量或参数不会被系统回收(不会释放内存)

闭包的写法: 函数嵌套函数,并return 里面的函数,这样就形成了闭包。

main() {fn() {var a = 123; /*不会污染全局   常驻内存*/return () {a++;print(a);};}var b = fn();b();//124b();//125b();//126
}