检查一下你的Flutter项目里有多少这样的代码

  1. if(xxx != null && xxx.isNotEmpty)

不得不说,我真的不喜欢这种先想条件,然后再想着在外面包一层 if 这种逆着思维顺序的代码方式(毕竟大家都活在「TENET」的世界里😏),尤其 if 里的条件比较长的时候。

消灭 == null

众所周知,dart 里有 ?.?? 这种判空操作符,于是上面的代码可以简化成这样:

  1. String a = "dart";
  2. if (a?.isNotEmpty ?? false) {
  3. print('😏');
  4. }

但是还是好麻烦呐

封装一个扩展函数试试

给常用的类型添加 isNullOrEmpty 扩展函数

  1. extension MapExtension on Map {
  2. bool get isNullOrEmpty => (this == null || this.isEmpty);
  3. }
  4. extension IterableExtension on Iterable {
  5. bool get isNullOrEmpty => (this == null || this.isEmpty);
  6. }
  7. extension StringExtension on String {
  8. bool get isNullOrEmpty => (this == null || this.isEmpty);
  9. }

好了现在我们可以这样写:

  1. String a = null;
  2. if (!a.isNullOrEmpty) {
  3. print("😒");
  4. } else print("Shit");

但是还有一种场景是不处理 null 的分支,只处理 empty or notEmpty

把 Kotlin 的方案搬过来,对bool类型加扩展函数

先写用法:

  1. String a = "";
  2. a?.isEmpty?.yes(() {
  3. print("Yes!");
  4. })?.orElse(() {
  5. print("No! God No!");
  6. })

如果你还是想要判断空分支,那还可以在后面加上??

看起来没有 kotlin 那么美观,但是至少不用写 if 了,代码实现在下面👇

  1. class BooleanExt<T extends Object> {
  2. T orElse(T block()) {
  3. if (this is OrElse) {
  4. return block() ?? Null;
  5. } else {
  6. return (this as WithData).data ?? Null;
  7. }
  8. }
  9. }
  10. class OrElse extends BooleanExt<Object> {}
  11. class WithData<T> extends BooleanExt<T> {
  12. final T data;
  13. WithData(this.data);
  14. }
  15. extension BoolExtension<T> on bool {
  16. BooleanExt yes(T block()) {
  17. if (this) {
  18. return WithData(block());
  19. } else {
  20. return OrElse();
  21. }
  22. }
  23. BooleanExt no(T block()) {
  24. if (this) {
  25. return OrElse();
  26. } else {
  27. return WithData(block());
  28. }
  29. }
  30. }

以上代码都基于现在稳定版的语法,不过前段时间 Dart 发布了一个实验特性,加入了空安全的完整版

新版 Dart 的「空安全」

新的空安全机制改得和 Kotlin 一样了,直接分成「可空」和「不可空」两大类型,一个变量允许赋值为null就必须提前声明为不可空类型,各位可以在 https://nullsafety.dartpad.cn/ 这里玩一下。
在新版空安全下,上面的 isNullorEmpty 的实现和调用得改成这样:

  1. extension IterableExtension on Iterable? {
  2. bool get isNullOrEmpty => (this == null || this!.isEmpty);
  3. }
  4. ///
  5. List<String>? a = null;
  6. if (a.isNullOrEmpty) {
  7. print("DOG");
  8. } else {
  9. print("Cat");
  10. }

emmm,可以发现这个语言还是不太聪明的样子,我明明前面都写了 this == null ||, 后面调用还是要加上 ! 操作符强制认定不为空,在 Kotlin 里,这里就可以智能判断,Kotlin 真香🌝。

总结

Dart 虽然开始的时候比较简陋,但是一直在进步,有了扩展函数,有了严格的空安全,下一步是不是可以考虑支持 DSL 语法了😏