到底是不是
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的Safe Calls,不贅述。
- 空感知方法呼叫,同樣不多說。
可見,Dart 雖然缺乏嚴格的空安全型別系統,但是在使用側利用空感知操作符這種語法糖相比 Java 簡化了判空操作,空感知賦值操作符甚至是 kotlin 都缺乏的(雖然可以用 Elvis 間接實現),某種意義上是靈活地實現了空安全。
為Dart正名
Dart 到底是不是空安全的,大家現在應該心裡有數了。其實Dart作為Google在2011年開源的現代語言,肯定是有從其他語言上吸取很多教訓,解決了很多痛點的,畢竟Google當初還想用他來取代 JS 成為下一代Web開發語言來著(雖然失敗了:) 。我剛開始接觸這門語言的時候,也覺得沒 Kotlin 用著舒服,但在深入的使用後發現 Dart 也是很優秀的。Dart 同時也在茁壯成長(看 Dart 的 Github 就知道),Google對他傾注了很多精力,我們要對它有信心哈。