Dart空安全介紹

Null Safety in Dart --- Introduction (Dart空安全介紹)

歷史

2020年11月空安全進(jìn)入Beta測試階段, 自2.12及Flutter2.0之后開始全面支持Sound null safety

介紹

一般來說畦戒,變量儲存了某些值。例如整數(shù)可以是0, 42, -2暖释;一個String可以是 hello world熊经,或者其他什么的內(nèi)容。

// In null-safe Dart, none of these can ever be null.
var i = 42; // Inferred to be an int.
String name = getFileName();
final b = Foo();

但是對大部分包括Dart在內(nèi)的編程語言而言斥黑,還有一種空值的概念弟胀,也就是沒有值埃跷。
例如,我喜歡的顏色這個變量邮利,可以是空值,這是合理的垃帅。有些人就是沒有喜歡的顏色延届。

    setBackground(my.favoriteColor); 

這就產(chǎn)生了一個問題,如果變量既可以是一種類型贸诚。例如整數(shù)或者顏色方庭,又可以是空厕吉,那么你每次使用的時候,都要想一想械念,
這個顏色變量到底存儲了真的顏色值头朱,還是空的顏色值?這一串整數(shù)數(shù)列里的某一個值龄减,到底是整數(shù)项钮,還是空值? ?? 呀噠

事實(shí)證明希停,程序員開發(fā)時不會一天到晚想著這個問題烁巫,常常制造出跟空值有關(guān)的錯誤。NullPointException可不是好東西宠能。 你的應(yīng)用會因此而奔潰亚隙,用戶可不喜歡這樣。

在默認(rèn)設(shè)定中违崇,Dart假設(shè)你的變量都不是空值阿弃。例如,年齡變量不可為空羞延,你不能將它設(shè)為空值渣淳。這有點(diǎn)像雙重否定的概念(Filip Hracek說的)。

    my.age = null;  // 我靠這是什么, 你的年齡竟然是空肴楷。 ???何者じゃ水由?

換個說法,年齡變量一定是某個數(shù)值赛蔫,不可以是空值砂客。這是默認(rèn)設(shè)定,所有類型的默認(rèn)都是不可為空呵恢。

不過你還是可以使用空值鞠值,但是你要明確的說明。 如果要容許favoriteColor使用空值渗钉,就要加上問好彤恶。這個變量就可以為空。它既可以是顏色值鳄橘,也可以是空值声离。因?yàn)槲覀円呀?jīng)明確標(biāo)識了。

    setBackground(my?.favoriteColor); 

現(xiàn)在Dart可以幫助我們避免剛才提到的問題瘫怜,如果你使用favoriteColor為color术徊,忘記它可能是空值,Dart就會提醒你鲸湃,這樣你的代碼就更安全了赠涮。

另外子寓,Dart的空安全頁很靠譜。(Filip Hracek說的)笋除。

如果Dart判斷某個變量不可為空斜友,那個變量就從頭到尾就都不可為空。IDE中已經(jīng)會通過上下文做出判斷檢測垃它,不僅僅檢測一行代碼哦鲜屏。正所謂編譯時報(bào)錯,而非運(yùn)行時報(bào)錯了嗤瞎。

許多其他的程序語言并沒有靠譜的空安全機(jī)制墙歪。經(jīng)常要在運(yùn)行期間進(jìn)行檢查。

NullSafety Sound NullSafety
C# X
Dart X X
Java X
Kotlin X
Swift X X
TypeScript X

而且Dart與Swift共享靠譜的空安全機(jī)制贝奇,其他語言可說不準(zhǔn)了虹菲。由于Dart的空安全機(jī)制很靠譜,它還可以令你的程序運(yùn)行得更快掉瞳。不但更安全毕源,而且更迅速。
各位程序員陕习,這對你來說代表什么呢霎褐???

我前面說過,大部分變量一定有某種類型的值该镣,絕不會沒有值冻璃,也就是說,他們不可為空损合。這是比較好懂的說法省艳。比"它們不可以有一個什么都沒有的值"好一點(diǎn)。

因此嫁审,你大部分的代碼應(yīng)該看起來像這樣: 沒有問好(?.)跋炕,沒有空值判斷(!),什么都沒有律适。

int fibonacci(int n) {
    if (n <= 1) return 1;
    return fibonacci(n - 1) + fibonacci(n - 2);
} 

void main() {
    print(fibonacci(10));
}

如果你覺得某個變量可能會出現(xiàn)空值辐烂,你就必須明確的標(biāo)識它可以為空。方法就是加上問好捂贿。

Color? favoriteColor 

void setBackground(Color? color) {
    // ...
}

Color? chooseFavorite() {
    // ...
}
List<Color?> favorites;

它不但可以用在聲明變量的時候纠修,還可以用在函數(shù)參數(shù)、返回值厂僧,范型等等分瘾。

Dart還會幫助你避免跟空值有關(guān)的錯誤。基本上他會要你在適當(dāng)?shù)牡胤郊由峡罩禉z查德召,并且處理空值出現(xiàn)的情況。

void setBackground(Color? color) {
    // ...
}

Color definitelyColor = Color(0xffff00ff);
setBackground(difinitelyColor);  // 這是對的

你可能先前忘記處理了汽纤。如果是介于兩者之間的情況呢上岗?如果你將一個不可能為空的變量,傳給可空的字段蕴坪,是沒有問題的肴掷。
一個不可為空的顏色變量,可以傳給一個接受空值參數(shù)的函數(shù)背传,可是反過來的話呆瞻,就沒有那么簡單了。一個可為空的顏色變量径玖,就不可以傳給參數(shù)不可為空的函數(shù)痴脾。

void setBackground(Color color) {
    // ...
} 

Color? definitelyColor = null;
setBackground(definitelyColor);   // 這是錯誤的

換句話說,如果你的函數(shù)說梳星,我不接受空值赞赖,我的參數(shù)都不可為空,你就不能將可能為空值的東西丟給它冤灾。這種情況怎么處理前域????

實(shí)踐

有幾種可能的做法。

  1. 完全不要調(diào)用這個函數(shù)韵吨,如果你知道變量是空值匿垄。
  2. 你知道變量是空值的,就改用別的變量归粉。提供默認(rèn)值椿疗。
  3. 使用感嘆號,強(qiáng)迫使用空值盏浇。這跟寫一段空值檢查很類似变丧。并在失敗時拋出異常。這個類雖可為空值绢掰,但你只有在100%確定這個變量不是空值的情況下才可以使用這個方法痒蓬。
setBackground(definitelyColor ?? black);

setBackground(definitelyColor!);

比如說滴劲,你知道這個程序的運(yùn)作背景攻晒,而Dart卻無從得知。不過大部分情況下班挖,<font color="red">你應(yīng)該盡量避免使用感嘆號鲁捏。</font>
就這樣,空安全令你的代碼更安全萧芙,運(yùn)行的更快速给梅,對你編寫方式的影響也降到最小假丧。

舊項(xiàng)目遷移

如果有興趣可以看下Dart提供了命令行工具,來轉(zhuǎn)化你的舊代碼到NullSafety的遷移动羽。

dart migrate 

請到dart.dev/null-safety查閱更多資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末包帚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子运吓,更是在濱河造成了極大的恐慌渴邦,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拘哨,死亡現(xiàn)場離奇詭異谋梭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)倦青,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門瓮床,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人姨夹,你說我怎么就攤上這事纤垂。” “怎么了磷账?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵峭沦,是天一觀的道長。 經(jīng)常有香客問我逃糟,道長吼鱼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任绰咽,我火速辦了婚禮菇肃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘取募。我一直安慰自己琐谤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布玩敏。 她就那樣靜靜地躺著斗忌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪旺聚。 梳的紋絲不亂的頭發(fā)上织阳,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機(jī)與錄音砰粹,去河邊找鬼唧躲。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弄痹。 我是一名探鬼主播饭入,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼肛真!你這毒婦竟也來了圣拄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤毁欣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后岳掐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凭疮,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年串述,在試婚紗的時候發(fā)現(xiàn)自己被綠了执解。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡纲酗,死狀恐怖衰腌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情觅赊,我是刑警寧澤右蕊,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站吮螺,受9級特大地震影響饶囚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鸠补,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一萝风、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧紫岩,春花似錦规惰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至梨与,卻和暖如春堕花,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背粥鞋。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工缘挽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓壕曼,卻偏偏與公主長得像苏研,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子腮郊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容