Dart 危险的空值判断

1,498 阅读3分钟

起因

前段时间为上线了一个功能,然后开始有用于反馈bug 开始只有个别用户出现问题,后来大量的用户出现相同的问题。经过一天的紧张排查 后来终于锁定的问题出现的原因 if(result){} result被后来的一个业务给置为null。导致了后续的操作没有执行

空值判断

在Dart语言里面一切数据类型都是Object类型,int bool double 也不例外 既然是object类型 那么 就有可能为null。今天我想讨论的是关于处理null值类型的情况 我们应该如何写好代码,也许你对以下类似的代码并不陌生 或许 if(result){...}这样的代码 你会经常的使用,并不认为这样写有什么问题,可是你要注意 dart里面if语句中是不允许为null。 所以当result在其他的地方被你的业务逻辑置为null那么这样的代码就会报错 就像下面这样 一旦这样的代码发布生产环境那么 这个方法在 if(result)之后将不在执行,所以我认为这样写 始终会是一个潜在的隐患。也许你并不认为这样写是个太大的问题。
     试想一下,如果此时产品特别着急上线一个功能(当然了 可能产品也是被逼的。。)恰好负责该业务的同学请假了不在公司,这时候要你去解决这个问题,你可能需要一点时间去了解该功能的业务逻辑 然后还要加一些代码,产品、测试、老板 都在等你,都在看着你 你会不会因此疏忽了 这种情况,而且这样的问题 目前dart编译器也没有给你报错,然后你交付给了测试,测试在再测时候当时业务并没有出现 null 但是上线以后大量的用户各种各样的业务 导致 result = null, 那不就凉凉了。
所以我认为 正确的书写风格应该是 if(result == true){} 这样就避免该问题的发生。

关于空值类型的安全

这种错误不容易在开发阶段暴露出来,蛋疼的是编译器也不会给任何提示给开发人员。当初这个问题暴露出来以后,让我甚是怀念swift 如果是swift的话那么这个问题可能在编译期间就暴露出来了。所以基与对于空值类型的安全的呼声越来越高。Google在 dart 在2.12 之后加入了 Null Safety

什么是 Null Safety

也就是说在 dart2.12之后 所以的数据类型默认都是不能为null的了 所以像if(resut){}这样的代码就过不了编译器了 我们可以清晰的看到编译给报错了.
当然如果你需要这个值可以被值为null 那么你可以这么写
bool? result = false; 看见没 编译器又给报错了。
关于 Null Safety的更多用法请移步官方文档 dart.dev/null-safety

最后:这世界上哪有突如其来的的改变,全都是“蓄谋已久”的厚积薄发。