前言
Dart语言中有许多语法糖或者说lambda表达式,语法和代码量是简洁了许多,但给想要入门的我添加了许多困扰,我经常看官方API或者第三方文档API的时候,在示例中大量的使用了类似的语法糖,让代码的可读性大大下降,要搜索很多文章查看才能理解这段代码到底是啥意思,这篇文章是我自己做的一些语法糖汇总。
语法糖 or lambda表达式
1、方法及其胖箭头 (=>)
因为dart中真正实现了万物皆可为对象,所以dart中的方法(Function)也是一个类(class)。
dart虽然是强类型语言,但变量可以用var来声明,凭借着dynamic的动态类型在运行时可以推断出变量的类型是什么,方法自然也不例外,你在声明方法的时候可以把返回类型省略(官方并不推荐这么做)
如下:
add(int x,int y){
return x+y;
}
main(){
print(add(2, 3));
}
运行后控制台如下:
5
这时如果我们查看add()方法返回值类型是什么就会发现果不其然是dynamic——动态数据类型
在日常使用中,建议方法前的返回类型还是不要省略,明确的指出返回类型会大大提升代码的可读性。
在dart中如果方法只有一行语句时,就可以使用胖箭头(=>)来代替方法体,比如上方的add()方法
如下:
int add(int x,int y) => x + y ;
void main(){
print(add(2, 3));
}
2、call()方法
dart中一个类如果有一个方法名为 "call" 的方法则可以用()直接调用
如下:
class Computer{
Computer(){
print('01');
}
Computer.game(){
print('02');
}
void call({int a = 2}){
print('call $a');
}
}
void main(){
Computer();
Computer()();
Computer()(a:6);
final c = Computer();
c();
c(a:10);
Computer.game()();
Computer.game()(a:111);
}
控制台打印为:
01
01
call 2
01
call 6
01
call 2
call 10
02
call 2
02
call 111
3、 声明可空(?)和空断言运算符(!)
dart2.12后默认都是开启了空安全的,也就是说你平时声明的变量在确定类型的时候是不能为空的,例如下方这样的声明就是错误的,编译器会在编译时就报错
int a = null;
想要声明为空变量可以在声明时的类型后方添加 ? 来表示该类型可为空,未赋值时所有变量默认值都是null
int? a;
如果声明了该变量可为空时,在方法调用或者使用变量可能为空时,会报编译时错误:
这时就可以用空断言运算符来表示你调用的对象确信不为空:
int? getNum() => 1;
void main(){
var c = getNum();
print(c!.abs());
}
或者在(.)之前加上(?)来表示可空
int? getNum() => 1;
void main(){
var c = getNum();
print(c?.abs());
}
4、 ?? 和 ??= 避空运算符
声明可空变量时可以使用避空运算符来赋值防止变量为空
int? a; // = null
a ??= 3;
print(a); // <-- Prints 3.
a ??= 5;
print(a); // <-- Still prints 3.
在使用时可以用??防止变量为空
print(1 ?? 3); // <-- Prints 1.
print(null ?? 12); // <-- Prints 12.
5、级联运算符(..)
dart中可以用级联运算符对同一对象进行连续调用:
class Player{
int ammo = 3;
void walk() => print('walk');
void run() => print('run');
void fire(int a){
if(ammo >= a){
print('ta'*a);
ammo -= a;
}
}
}
Player? getPlayer() => Player();
void main(){
getPlayer()
?..walk()
..run()
..fire(3);
}
这里可以和空判断一起使用,使用(?..)可以确保在对象不为null时执行。
运行如下:
walk
run
tatata
6、lambda
forEach()
String scream(int length) => 'A${'a' * length}h!';
main(){
final values = [1,2,3,5,10,50];
// for(var length in values){
// print(scream(length));
// }
// values.map(scream).forEach(print);
//跳过1
//拿3个结果
values.skip(1).take(3).map(scream).forEach(print);
}