检查一下你的Flutter项目里有多少这样的代码
if(xxx != null && xxx.isNotEmpty)
不得不说,我真的不喜欢这种先想条件,然后再想着在外面包一层 if 这种逆着思维顺序的代码方式(毕竟大家都活在「TENET」的世界里😏),尤其 if 里的条件比较长的时候。
消灭 == null
众所周知,dart 里有 ?. 和 ?? 这种判空操作符,于是上面的代码可以简化成这样:
String a = "dart";if (a?.isNotEmpty ?? false) {print('😏');}
但是还是好麻烦呐
封装一个扩展函数试试
给常用的类型添加 isNullOrEmpty 扩展函数
extension MapExtension on Map {bool get isNullOrEmpty => (this == null || this.isEmpty);}extension IterableExtension on Iterable {bool get isNullOrEmpty => (this == null || this.isEmpty);}extension StringExtension on String {bool get isNullOrEmpty => (this == null || this.isEmpty);}
好了现在我们可以这样写:
String a = null;if (!a.isNullOrEmpty) {print("😒");} else print("Shit");
但是还有一种场景是不处理 null 的分支,只处理 empty or notEmpty
把 Kotlin 的方案搬过来,对bool类型加扩展函数
先写用法:
String a = "";a?.isEmpty?.yes(() {print("Yes!");})?.orElse(() {print("No! God No!");})
如果你还是想要判断空分支,那还可以在后面加上??
看起来没有 kotlin 那么美观,但是至少不用写 if 了,代码实现在下面👇
class BooleanExt<T extends Object> {T orElse(T block()) {if (this is OrElse) {return block() ?? Null;} else {return (this as WithData).data ?? Null;}}}class OrElse extends BooleanExt<Object> {}class WithData<T> extends BooleanExt<T> {final T data;WithData(this.data);}extension BoolExtension<T> on bool {BooleanExt yes(T block()) {if (this) {return WithData(block());} else {return OrElse();}}BooleanExt no(T block()) {if (this) {return OrElse();} else {return WithData(block());}}}
以上代码都基于现在稳定版的语法,不过前段时间 Dart 发布了一个实验特性,加入了空安全的完整版
新版 Dart 的「空安全」
新的空安全机制改得和 Kotlin 一样了,直接分成「可空」和「不可空」两大类型,一个变量允许赋值为null就必须提前声明为不可空类型,各位可以在 https://nullsafety.dartpad.cn/ 这里玩一下。
在新版空安全下,上面的 isNullorEmpty 的实现和调用得改成这样:
extension IterableExtension on Iterable? {bool get isNullOrEmpty => (this == null || this!.isEmpty);}///List<String>? a = null;if (a.isNullOrEmpty) {print("DOG");} else {print("Cat");}
emmm,可以发现这个语言还是不太聪明的样子,我明明前面都写了 this == null ||, 后面调用还是要加上 ! 操作符强制认定不为空,在 Kotlin 里,这里就可以智能判断,Kotlin 真香🌝。
总结
Dart 虽然开始的时候比较简陋,但是一直在进步,有了扩展函数,有了严格的空安全,下一步是不是可以考虑支持 DSL 语法了😏
