发布于 

【Dart】函数梳理

方法定义

1
2
3
4
5
6
7

dart自定义方法的基本格式:

返回类型 方法名称(参数1,参数2,...){
方法体
return 返回值 / 或无返回值;
}

定义方法的的几个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void printInfo() {
print('我是一个自定义方法');
}

int getNum() {
var count = 123;
return count;
}

String printUserInfo() {
return 'this is str';
}

List getList() {
return ['222', '111', '666'];
}

Dart没有public 、private等关键字,_ 下横向直接代表 private。

方法的作用域

1
2
3
4
5
6
7
8
9
10
11
12
13
void main() {

void outFun() {
innerFun() {

print('aaa');
}
innerFun();
}

// innerFun(); 错误写法
outFun(); // 调用方法
}

方法传参

一般定义:

1
2
3
4
5
6
String getUserInfo(String username, int age) {
// 形参
return "姓名:$username -> 年龄:$age";
}

print(getUserInfo('小明', 23)); //实参

Dart中可以定义一个带可选参数的方法 ,可选参数需要指定类型默认值:

1
2
3
4
5
6
7
8
9
10
11
12
13
void main() {
String getUserInfo(String username, [int age = 0]) { // age格式表示可选
// 形参
if (age != 0) {
return "姓名:$username -> 年龄:$age";
}
return "姓名:$username -> 年龄不详";
}

print(getUserInfo('小明', 28)); // 实参
// 可选就可以不传了
print(getUserInfo('李四'));
}

定义一个带默认参数的方法:

1
2
3
4
5
6
7
8
9
String getUserInfo(String username, [String sex = '男', int age = 0]){  // 形参
if(age != 0){
return "姓名:$username -> 性别:$sex -> 年龄:$age";
}
return "姓名:$username -> 性别:$sex -> 年龄不详";
}
print(getUserInfo('张三'));
print(getUserInfo('李四','男'));
print(getUserInfo('李梅梅','女',25));

定义一个命名参数的方法,定义命名参数需要指定类型默认值:(命名参数的好处是在使用时可以不用按顺序赋值,看下面代码)

1
2
3
4
5
6
7
String getUserInfo(String username, {int age = 0, String sex = '男'}) { // 形参
if (age != 0) {
return "姓名:$username -> 性别:$sex -> 年龄:$age";
}
return "姓名:$username -> 性别:$sex -> 年龄保密";
}
print(getUserInfo('张三',sex: '男',age: 20));

定义一个把方法当做参数的方法:(其实就是方法可以当做参数来用,这点和Kotlin也是一样的)

1
2
3
4
5
6
7
8
9
10
11
12
// 方法1 随便打印一下
fun1() {
print('fun1');
}

// 方法2 参数是一个方法
fun2(fun) {
fun();
}

// 调用fun2这个方法 把fun1这个方法当做参数传入
fun2(fun1());

箭头函数和函数的相互调用

箭头函数

在之前的学习中,知道可以使用forEach来遍历List,其一般格式如下:

1
2
3
4
List list = ['a', 'b', 'c'];
list.forEach((value) {
print(value);
});

而箭头函数就是可以简写这种格式:

1
list.forEach((value) => print(value));

箭头后面指向的就是方法的返回值,这里要注意的是:
箭头函数内只能写一条语句,并且语句后面没有分号(;)

对于之前map转换的例子也可以使用箭头方法来简化一下:

1
2
3
4
5
6
7
List list = [1, 3, 6, 8, 9];
var newList = list.map((value) {
if (value > 3) {
return value * 2;
}
return value;
});

这里就是修改List里面的数据,让数组中大于3的值乘以2。那用箭头函数简化后可以写成:

1
var newList = list.map((value) => value > 3 ? value*2 : value);

函数的相互调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 定义一个方法来判断一个数是否是偶数  
bool isEvenNumber(int n) {
if (n % 2 == 0) {
return true;
}
return false;
}
// 定义一个方法打印1-n以内的所有偶数
prinEvenNumber(int n) {
for (var i = 1; i <= n; i++) {
if (isEvenNumber(i)) {
print(i);
}
}
}
prinEvenNumber(10);

匿名方法、自执行方法及方法的递归

匿名方法

1
2
3
4
5
var printNum = (){
print(12);
};

printNum();

这里很明显跟Kotlin中的特性基本是一样的。带参数的匿名方法:

1
2
3
4
5
var printNum = (int n) {
print(n + 2);
};

printNum(3);

自执行方法

自执行方法顾名思义就是不需要调用,会自动去执行的,这是因为自执行函数的定义和调用合为了一体。当创建了一个匿名函数,并执行了它,由于外部无法引用的它的内部变量,所以在执行完就会很快被释放,而且这种做法不会污染到全局对象。看如下代码:

1
2
3
4
((int n) {
print("这是一个自执行方法 + $n");
})(666);
}

方法的递归

方法的递归无非就是在条件满足的条件下继续在方法内调用自己本身,看以下代码:

1
2
3
4
5
6
7
8
9
10
var sum = 0;
void fn(int n) {
sum += n;
if (n == 0) {
return;
}
fn(n - 1);
}
fn(100);
print(sum);

实现的是1加到100。

闭包

闭包是一个前端的概念,客户端开发早期使用Java可以说是不支持闭包,或是不完整的闭包,但Kotlin是可以支持闭包的操作。

闭包的意思就是函数嵌套函数, 内部函数会调用外部函数的变量或参数, 变量或参数不会被系统回收(不会释放内存)。所以闭包解决的两个问题是:

  • 变量常驻内存

  • 变量不污染全局

闭包的一般写法是

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

闭包的写法:

1
2
3
4
5
6
7
Function func() {
var a = 1; /*不会污染全局 常驻内存*/
return () {
a++;
print(a);
};
}

这里return匿名方法后,a的值就可以常驻内存了

1
2
3
4
var mFun = func();
mFun();
mFun();
mFun();

打印:2、3、4。