Dart中的运算符有两个比较特殊,一个是赋值运算??= ;另一个是条件表达式??
??=
如果为nil就赋值,如果有值就直接返回。
void main() {var a;a ??= 10; ///如果当a为空的话就赋值10a ??= 5; /// 此时a已经有值了所以直接返回a ??= 1;print(a);}

??
如果左边有值就直接返回左边,如果左边没有值就直接返回右边
void main() {var a;a ??= 10; ///如果当a为空的话就赋值10a ??= 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(); /// 0func(); /// 1func(); /// 2func(); /// 3var func1 = funA();func1(); /// 0func1(); /// 1func1(); /// 2}
