到底是不是
Dart 作为 Flutter 钦定的语言,随着 Flutter 的火热走进了我们的视线。网上有很多针对它的非议,其中就包括 空安全。比如,文章中有这么一段话。
- 记住, Dart 没有空安全,不要以为不加问号的地方就一定不是 null
- 凡是你没有初始化的地方全是 null !
不能说他错,但这段话很容易让人误解,仿佛 Dart 跟 Java 一样,没有空安全这个语言特性。那 Dart 到底是不是空安全的呢,应该说 Dart 在一定程度上是空安全的。到底是不是,取决于怎么定义空安全。
走进 Dart 的内心世界
上面那篇文章是拿 dart 跟 kotlin 比较得出的结论,kotlin 我们都比较熟悉了,的确是空安全的,这也是他与 Java 的主要区别和吸引人的特性。具体我们可以看, 简而言之kotlin的引用分可空和非空两种类型,对于可空类型则提供安全的调用方法比如 a?.foo()
,从而消灭 The Billion Dollar Mistake。与 Kotlin 比较, Dart可以说是 做了一半,其实 Dart 早在2015年8月的时候就在1.12版本中添加了一个针对空安全的语言特性——Null-aware operators
??
: if null operator.expr1 ?? expr2
evaluates toexpr1
if notnull
, otherwiseexpr2
.??=
: null-aware assignment.v ??= expr
causesv
to be assignedexpr
only ifv
isnull
.x?.p
: null-aware access.x?.p
evaluates tox.p
ifx
is notnull
, otherwise evaluates tonull
.x?.m()
: null-aware method invocation.x?.m()
invokesm
only ifx
is notnull
.
我尝试着解释下:
??
是判空操作符,表示如果??
左边的表达式不为空则是左边的值否则是右边的。比如int a = b ?? 1;
,如果 b 是空的,则 a=1,否则a=b。 是不是看着很眼熟?没错,这相当于 kotlin 中的 Elvis操作符?:
。??=
空感知赋值,被赋值的变量为空的时候才对他赋值。这个操作符其实相当于上一个的语法糖,a ??= b
等于a = a?? b
。- 空感知访问,相当于Kotlin的,不赘述。
- 空感知方法调用,同样不多说。
可见,Dart 虽然缺乏严格的空安全类型系统,但是在使用侧利用空感知操作符这种语法糖相比 Java 简化了判空操作,空感知赋值操作符甚至是 kotlin 都缺乏的(虽然可以用 Elvis 间接实现),某种意义上是灵活地实现了空安全。
为Dart正名
Dart 到底是不是空安全的,大家现在应该心里有数了。其实Dart作为Google在2011年开源的现代语言,肯定是有从其他语言上吸取很多教训,解决了很多痛点的,毕竟Google当初还想用他来取代 JS 成为下一代Web开发语言来着(虽然失败了:) 。我刚开始接触这门语言的时候,也觉得没 Kotlin 用着舒服,但在深入的使用后发现 Dart 也是很优秀的。Dart 同时也在茁壮成长(看 Dart 的 Github 就知道),Google对他倾注了很多精力,我们要对它有信心哈。