Dart 到底是不是空安全的

大膜導師控控發表於2019-02-20

到底是不是

Dart 作為 Flutter 欽定的語言,隨著 Flutter 的火熱走進了我們的視線。網上有很多針對它的非議,其中就包括 空安全。比如這篇文章,文章中有這麼一段話。

  1. 記住, Dart 沒有空安全,不要以為不加問號的地方就一定不是 null
  2. 凡是你沒有初始化的地方全是 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 to expr1 if not null, otherwise expr2.
  • ??=: null-aware assignment. v ??= expr causes v to be assigned expr only if v is null.
  • x?.p: null-aware access. x?.p evaluates to x.p if x is not null, otherwise evaluates to null.
  • x?.m(): null-aware method invocation. x?.m() invokes m only if x is not null.

我嘗試著解釋下:

  1. ?? 是判空操作符,表示如果??左邊的表示式不為空則是左邊的值否則是右邊的。比如 int a = b ?? 1;,如果 b 是空的,則 a=1,否則a=b。 是不是看著很眼熟?沒錯,這相當於 kotlin 中的 Elvis操作符?:
  2. ??= 空感知賦值,被賦值的變數為空的時候才對他賦值。這個操作符其實相當於上一個的語法糖,a ??= b 等於 a = a?? b
  3. 空感知訪問,相當於Kotlin的Safe Calls,不贅述。
  4. 空感知方法呼叫,同樣不多說。

可見,Dart 雖然缺乏嚴格的空安全型別系統,但是在使用側利用空感知操作符這種語法糖相比 Java 簡化了判空操作,空感知賦值操作符甚至是 kotlin 都缺乏的(雖然可以用 Elvis 間接實現),某種意義上是靈活地實現了空安全。

為Dart正名

Dart 到底是不是空安全的,大家現在應該心裡有數了。其實Dart作為Google在2011年開源的現代語言,肯定是有從其他語言上吸取很多教訓,解決了很多痛點的,畢竟Google當初還想用他來取代 JS 成為下一代Web開發語言來著(雖然失敗了:) 。我剛開始接觸這門語言的時候,也覺得沒 Kotlin 用著舒服,但在深入的使用後發現 Dart 也是很優秀的。Dart 同時也在茁壯成長(看 Dart 的 Github 就知道),Google對他傾注了很多精力,我們要對它有信心哈。

相關文章