Dart中的运算符有两个比较特殊,一个是赋值运算??=
;另一个是条件表达式??
??=
如果为nil就赋值,如果有值就直接返回。
void main() {
var a;
a ??= 10; ///如果当a为空的话就赋值10
a ??= 5; /// 此时a已经有值了所以直接返回
a ??= 1;
print(a);
}
??
如果左边有值就直接返回左边,如果左边没有值就直接返回右边
void main() {
var a;
a ??= 10; ///如果当a为空的话就赋值10
a ??= 5;
a ??= 1;
print(a);
var b;
b = 5;
print(b ?? a); /// 如果左边有值返回左边,如果左边没有值就直接返回右边
}
Function
Dart中的方法也是一个对象,返回值和参数类型可以省略。当方法的执行语句只有一句的时候,可以使用箭头函数=>
表达式
void main() => functionDemo();
void functionDemo() {
print('function');
}
void functionDemo() => print('function');
之前写C的时候定义一个sum函数,在Dart中参数类型可以省略,但是不建议这么写。
void functionDemo() {
print(sum(10, 10));
}
///int sum(int a, int b){
/// return a + b;
///}
/// 省略了参数类型之后
int sum(a, b){
return a + b;
}
可选参数
定义可选参数就必须带上形参的名字,传递参数的时候也必须带上形参的名字。
void main() => functionDemo();
void functionDemo() {
print(sum(1));
print(sum(1, b:2, c: 3));
print(sum(1, c:3));
}
sum(int a, {var b,var c}) {
b ??= 1;
c ??= 2;
return a + b + c;
}
那么上面的sum函数的bc的类型能都是int呢?
sum1(int a, {int b, intc}) {
return a + b + c;
}
结果直接报错不能为空。这个时候我们可以使用可以为空的类型nullability
sum1(int a, {int? b, int? c}) {
b ??= 1;
c ??= 2; /// int?告诉编译器,已经处理了后面为空的情况
return a + b + c;
}
可选参数也可以有默认值
sum1(int a, {int b = 0, int c = 0}) {
return a + b + c;
}
上面介绍的{}
里面的可选参数都是没有顺序的,使用[]
可以指定顺序
sum2(int a, [int b = 0, int c = 0]) {
return a + b + c;
}
print(sum2(1, 2, 3)); ///此时这么写就是按照a,b,c的顺序指定
方法作为参数传递
Dart万物皆对象,那么方法也是对象可以传递。
void main() {
var list = [1,2,3,4];
forEachDemo(list, printElement);
}
forEachDemo(List list, void func(var element)){
for(var e in list) func(e);
}
int b = 0;
printElement(var a) {
b++;
print('元素$b = $a' );
}
匿名函数
匿名方法说白了就是没有方法名称的方法!
void main() {
var list = [1,2,3,4];
/// 第一种写法:
var func = (){
print('匿名方法');
};
func();
/// 第二种写法:立即执行的方法、函数
(() {
print('我是一个立即执行的函数');
})();
}
匿名函数一般在什么场景下使用?上面介绍的方法做为参数传递,其实也可以写成这种匿名函数,虽然看起来像block(闭包), 但是还是跟block有区别的。
void main() {
var list = [1,2,3,4];
int b = 0;
forEachDemo(list, (var a) {
b++;
print('元素$b = $a');
});
}
forEachDemo(List list, void func(var element)){
for(var e in list) func(e);
}
闭包
closure:定义在函数里面的函数就是闭包,闭包也是一个对象。
闭包的作用:可以访问外部函数的局部变量。
funA() {
int count = 0;
return() =>print(count++); ///这个匿名函数就是闭包
}
void main() {
var func = funA();
func();
func();
func();
func();
}
如果闭包是值传递的话,那么每次调用的时候这里应该打印的都是0,那么实际上呢
所以闭包没有销毁之前,闭包内部访问的外部变量也不会被释放。
void main() {
var func = funA();
func(); /// 0
func(); /// 1
func(); /// 2
func(); /// 3
var func1 = funA();
func1(); /// 0
func1(); /// 1
func1(); /// 2
}