0%

【文章翻譯】Dart sound null safety: technical preview 2

【文章內容使用 Gemini 1.5 Pro 自動產生】

宣布 Flutter 架構的空安全支援

Dart 在 Flutter 中扮演著特殊的角色,為開發人員功能(如熱重載)提供動力,並透過 Dart 的靈活編譯器技術,為行動、桌面和網頁實現跨平台應用程式。我們致力於使 Dart 語言成為 Flutter 應用程式開發人員最具生產力的語言;例如,我們加入了 UI-as-code 語言結構,以優化 Dart 語法,用於編寫 Flutter Widget 樹。

在 6 月份,我們提供了 Dart 空安全的首個技術預覽。今天是另一個重要的里程碑,我們已經 期待已久:我們宣布 健全的空安全 的第二個技術預覽,包括對 Flutter 架構的支援。

空安全是一個主要的生產力功能,可以幫助您避免空引用錯誤,這種類型的錯誤通常很難發現。作為額外的優點,此功能還可以實現一系列效能改進。我們非常期待您的回饋。

為什麼要使用空安全?

Dart 是一種類型安全的語言。這表示當您獲得某種類型的變數時,編譯器可以保證它屬於該類型。但是,類型安全本身不能保證變數不是空引用。

空引用錯誤非常普遍。在 GitHub 上搜尋會發現由於 Dart 程式碼中出現意外的空引用而導致的數千個問題,以及數千個嘗試解決這些問題的提交。試著看看您是否能在下面的 Flutter 應用程式中發現可空性問題,想像 Config 和 WeatherService 是應用程式使用的後端服務:

如果 getAppName() 返回空引用,這個應用程式肯定會失敗;在這種情況下,我們將傳遞空引用給 AppBar 標題中使用的 Text Widget。

但是,還有更多微妙的情況需要考慮:getTemperatures() 也可能返回空引用。在這種情況下,for 迴圈會失敗。或者 getTemperatures() 可以像預期一樣返回一個列表,但該列表可能包含空值,在這種情況下,我們將呼叫 round() 到空引用上,應用程式將會失敗。

空安全功能透過 驗證您的程式碼 來解決這些問題,就像您在輸入時一樣:

Screenshot of the preceding code with null errors.
利用空安全,Dart 會在您的程式碼中找到潛在的空引用錯誤。

利用空安全,您可以更有信心地推論您的程式碼。部署的應用程式中不再有惱人的運行時空引用解除引用錯誤。相反,您在編寫程式碼時會出現靜態錯誤。

空安全原則

Dart 空安全支援基於以下三個核心設計原則:

  1. 預設不可空引用。除非您明確告訴 Dart 變數可以為空引用,否則它將被視為不可空引用。我們選擇這一點作為預設值,因為我們發現不可空引用是 API 中最常見的選擇。
  2. 可遞增採用。有很多 Dart 程式碼。您可以選擇在您想要的時候遞增地逐漸遷移到空安全,然後逐部分地進行遷移。可以在同一個專案中使用空安全的程式碼和非空安全的程式碼。我們還將提供工具來幫助您進行遷移。
  3. 完全健全。Dart 的空安全是 健全 的。這表示我們可以信任類型系統:如果它確定某個東西不是空引用,那麼它 永遠 不會是空引用。這可以實現編譯器最佳化. 當您將整個專案和相依項目遷移到空安全後,您將完全享受到健全性帶來的優勢 - 不僅是更少的錯誤,而且還包括更小的二進位檔案和更快的執行速度。

讓我們更詳細地回顧一下這些設計原則。

1. 預設不可空引用

核心語法非常簡單。以下是一些以不同方式宣告的不可空引用變數。請記住,不可空引用是預設值,所以這些宣告看起來與今天一樣,但它們的含義發生了變化。

Dart 會確保您永遠不會將空引用指派給上述任何變數。如果您嘗試執行 widget = null,幾千行程式碼之後,您將得到一個靜態分析錯誤和紅色的波浪線,您的程式將拒絕編譯。

可空引用變數

如果您想要您的變數可以為空引用,您可以使用 ?,比如這樣:

您可以在函數參數和返回值中使用 ? 語法,也是如此:

但是,再次強調,夢想是您很少需要使用 ?。您的絕大多數類型將是不可空引用。

使用空安全提高生產力

空安全不僅僅是關於安全。我們還希望您在使用此功能時能夠提高生產力,這表示此功能必須易於使用。例如,請看以下程式碼,它使用 if 來檢查空引用值:

請注意,Dart 工具如何檢測到當我們通過該 if 語句時,loudness 變數不可能為空引用。因此,Dart 讓我們可以呼叫 clamp() 方法,而無需跳躍障礙。這種便利性是由一種稱為流程分析的功能實現的:Dart 分析器會像執行程式一樣遍歷您的程式碼,自動找出有關程式碼的更多資訊。

以下是一個示例,它顯示了一個情況,即 Dart 可以確定變數為不可空引用,因為我們始終將不可空引用值指派給它:

如果您移除上述任何指派(例如,透過刪除 statusText = 'Update failed'; 這行程式碼),Dart 無法保證 statusText 為不可空引用:您將得到一個靜態錯誤,您的程式碼將無法編譯。您可以 在 DartPad 中嘗試一下

2. 可遞增採用

由於空安全對我們的類型系統來說是一個如此基礎性的改變,如果我們堅持強制採用,這將是極其破壞性的。我們希望讓您自行決定何時是適當的時間,因此空安全是一個選擇性功能:您將能夠使用最新的 Dart 和 Flutter 版本,而無需在您準備好之前強制您啟用空安全。您甚至可以從尚未啟用空安全的應用程式或套件中相依於已經啟用空安全的套件。

一旦您選擇採用,我們強烈建議您按照順序遷移程式碼,相依關係圖的葉節點優先遷移。例如,如果 C 相依於 B,而 B 相依於 A,則先將 A 遷移到空安全,然後是 B,最後是 C。此順序適用於 A、B 和 C 是函式庫、套件還是應用程式。

為什麼順序很重要?儘管您可以在相依項目遷移之前進行一些程式碼遷移,但如果相依項目在遷移期間更改了它們的 API,您可能會冒著需要進行第二次遷移的風險。當我們到達 beta 版本時,我們將提供工具來幫助您找出哪些相依項目已經遷移。如果您是套件作者,為了避免 API 斷裂的風險,請在發佈空安全的版本之前,等待所有相依項目都完成遷移。

當您的相依項目準備就緒時,您可以使用我們的遷移工具。該工具透過分析您所有現有的程式碼來工作。遷移工具是互動式的,因此您可以審查工具推斷出的可空性屬性。如果您不同意工具的任何結論,您可以添加可空性提示來更改推斷。添加幾個遷移提示會對遷移品質產生巨大的影响。

Screenshot of the migration tool
遷移工具有助於您以互動方式將程式碼遷移到空安全。

3. 完全健全

一旦您完全完成遷移,Dart 的空安全就是 健全 的。這表示 Dart 100% 確定在上面的示例中,返回值、列表和元素不可能為空引用。當 Dart 分析您的程式碼並確定變數為不可空引用時,該變數 始終 為不可空引用:如果您在偵錯工具中檢查正在執行的程式碼,您將看到不可空引用性在運行時被保留。相反,其他一些實作是非健全的,在許多情況下仍然需要執行運行時空引用檢查。Dart 與 Swift 共享 健全的空安全,但其他程式語言卻很少。

Dart 空安全的健全性還有另一個令人欣慰的含義:這表示您的程式可以更小更快。由於 Dart 非常確定不可空引用變數永遠不會為空引用,因此 Dart 可以進行最佳化。例如,Dart 的提前編譯 (AOT) 編譯器可以生成更小更快 Native 程式碼,因為它不需要在知道變數不是空引用時添加空引用檢查。

請注意,要獲得健全的空安全,您需要將整個專案和所有相依項目遷移到空安全。如果您的應用程式或相依項目的一部分尚未遷移,您將獲得部分空安全,它保留了大部分檢查,但沒有完全最佳化,也無法保證應用程式完全安全。

空安全路線圖

空安全何時才能準備好投入生產使用?以下是目前的時間表:

  1. Flutter 進行 技術預覽 2 嘗試:這就是今天。由於我們已成功將核心 Flutter 架構遷移到空安全,因此您可以嘗試使用空安全來學習新的語言功能併嘗試 一個小型 Flutter 樣本。如果您是套件作者,您也可以嘗試遷移,如果您有一個小型相依項目集已經被我們遷移了。您需要傳遞一個 實驗標誌,不應該在生產環境中使用它,也不應該發佈任何遷移的套件。
  2. 使用 beta 版本進行早期套件遷移:今年晚些時候,我們將完成效能調整,並擁有足夠的測試覆蓋率,讓我們有信心相信此功能按預期工作,並且向後相容性穩定。在那時,我們將發佈該功能的 beta 版本,您將不再需要傳遞實驗標誌。我們希望看到套件擁有者開始將他們的套件遷移到空安全,這將為我們提供最後一輪驗證,證明該功能已準備好發佈穩定版本。
  3. 使用 stable 版本投入生產:接下來,我們將解決 beta 版本中收到的回饋,修復任何剩餘的問題,然後發佈到 stable channel。很難為此設定一個具體的時間表,但我們認為是明年年初。一旦該功能穩定,我們希望看到空安全被廣泛採用,會有空安全的應用程式發佈到商店,以及許多空安全的套件在 stable channel 上發佈到 pub.dev。

立即嘗試

您今天就可以開始嘗試使用空安全!若要快速上手,請查看 附帶空安全的 DartPad 特殊版本

如果您想在 VS Code、Android Studio 或終端機中嘗試使用空安全,請查看 Flutter 空安全樣本應用程式。這個應用程式包含執行說明和一個小型氣象應用程式的兩個版本:一個不使用空安全,其中包含一些零散的空引用錯誤,另一個使用空安全來確保這些問題得到處理。如果您更願意嘗試使用一個新的 Flutter 應用程式,您可以運行 flutter create,然後按照 實驗說明 來啟用空安全。請注意,您將需要一個 dev channel 的 Flutter SDK(版本 1.24.0–3.0.pre 或更高版本),因為目前的穩定版本和 beta 版本的 Flutter 不支援空安全。

若要進一步了解功能設計,請閱讀我們最新的 了解空安全 文件。如果您更喜歡觀看簡短的影片,請查看幾個月前 Flutter Day 活動 中的 空安全影片

我們很高興將健全的空安全帶到 Dart。健全的空安全是 Dart 的一個特色功能,可以幫助您編寫更不易出錯的程式碼,並獲得更好的效能。我們希望您會 嘗試 在技術預覽中使用此功能,並透過我們的議題追蹤器 提供回饋。祝您編碼愉快!


Dart 健全的空安全:技術預覽 2 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

http://creativecommons.org/licenses/by/4.0/