Dart 3.2 更新盤點
作者 / Kevin Moore 和 Michael Thomsen
我們隆重宣佈推出 Dart 3.2,這一版本針對以下方面做出了改進: 新增了一項語言功能,可對私有 final 欄位進行非空升級;透過新增的互操作功能改善了開發者體驗;支援 DevTools 的擴充套件程式;並更新了我們的 Web 路線圖,包括提供對 Wasm (又名 WebAssembly) 的支援。
私有 final 欄位的非空升級
自我們在 Dart 2.12 中引入 健全的空安全 (sound null safety) 以來已過去幾年時間。你可以藉助空安全宣告哪些型別可為空 (可以包含值或 null),哪些型別不可為空 (始終包含值)。透過將空安全與 流程分析 相結合,能夠檢測何時可以將可為空的變數 “升級” 為更安全的非空型別:
int definitelyInt(int? aNullableInt) {
if (aNullableInt == null) {
return 0;
}
// If flow analysis reaches this point,
// aNullableInt can safely promote to a non-null int.
return aNullableInt;
}
自 Dart 2.12 發布以來,型別升級一直是空安全的核心部分,但僅限於區域性變數。欄位或頂級變數無法升級,例如以下程式碼範例:
class Container {
final int? _fillLevel;
Container(this._fillLevel);
check() {
if (_fillLevel != null) {
int i = _fillLevel; // Prior to Dart 3.2, causes an error.
}
}
}
這種侷限性由多種複雜的情況導致。在這些情況中,流程分析無法安全地確定欄位何時或如何變化。以類別上的欄位升級為例,如果子類別使用 getter 覆蓋欄位,可能會存在問題,因為有時會回傳 null。
在 Dart 3.2 中,我們改進了流程分析引擎,現在能夠對私有 final 欄位實施型別升級。現在,上面的程式碼範例可以正常執行。你可以這樣理解: 對於私有 final 欄位,它的值在初始分配後永不更改,因此僅檢查一次也是安全的。私有 final 欄位升級從 Dart 3.2 起推出,並將應用於設定 3.2 及以上版本 Dart SDK 的專案。
在 package:lints 3.0 中加入新的程式碼分析選項
針對程式碼分析,我們還對 package:lints 中的標準程式碼分析規則進行了一些改進。此 package 包含預設和推薦的靜態分析規則集,適用於任何根據 dart create 或 flutter create (透過 package:flutter_lints — package:lints 的擴充套件) 建立的新專案。
此 lint 集新的主要版本 (版本 3.0) 現已推出。我們在此修訂版的核心集中新增了六個 lint,在推薦集中新增了兩個 lint,可用於驗證 pubspec URL,以及驗證是否使用正確的引數呼叫集合方法等。你可以檢視 更新日誌 獲取完整的更改清單。3.0 版本將成為即將發布的新專案的預設版本。你也可以 立即升級 現有專案。
Dart 互操作性更新
提供 廣泛的跨平臺支援 一直是 Dart 的核心原則。但是,即使一行 Dart 程式碼可以做到無需更改就能在所有平台上執行,大型應用通常仍然需要與現有程式碼進行互操作。現有程式碼指舊專案的程式碼,或其他庫中可用的 API 或系統 API。我們在這一領域投入了大量精力,首先是用於 與原生 C API 進行互操作 的 FFI。我們目前正在努力擴大該領域,以支援與 Java、Kotlin、Objective C 和 Swift 的互操作。你可以閱讀下文 Dart Web 部分,瞭解有關 JS 互操作性的精彩更新。
從 Dart 3.2 開始,我們對原生互操作進行了許多改進:
-
我們為 C FFI 引入了 NativeCallable.isolateLocal 建構式函式,它可以根據任意 Dart 函式建立 C 函式指標。這是一項由 Pointer.fromFunction 提供的擴充套件功能,只能根據頂級函式建立函式指標。
-
我們更新了 Objective-C 繫結產生器,以使用在 Dart 3.1 中新增的 NativeCallable.listener。該產生器現在可以自動處理包含非同步回呼的 API,例如 Core Motion 這類此前需要手動編寫部分繫結程式碼的 API。
-
我們為實現 Java 和 Kotlin 互操作而持續改進 package:jnigen。現在能夠將 package:cronet_http (適用於 Android 的 Cronet HTTP 用戶端的封裝容器) 從手寫的繫結程式碼遷移到 自動生成的封裝容器。
-
我們在 Native Assets 功能方面取得了重大進展,該功能旨在解決與依賴原生程式碼的 Dart package 分發相關的許多問題。Native Assets 提供統一的鉤子來整合建立 Flutter 和獨立 Dart 應用所涉及的各種建立系統,從而解決相關問題。你可以檢視相關 文件 獲取預覽。
適用於 Dart package 的 DevTools 擴充套件程式
Dart DevTools 是一套用於支援純 Dart 和 Flutter 應用的除錯及效能工具。我們在 Dart 3.2 和 Flutter 3.16 中 推出 了新的 擴充套件框架,讓 package 作者能夠直接在 DevTools 中為其 package 建立自定義工具。因此,包含框架的 pub.dev package 能夠提供特定於其用例的自定義工具。例如,Serverpod 的作者一直在努力為其 package 建立 DevTools,並且很高興在即將發布的 1.2 版本 中提供 DevTools 擴充套件程式。
△ 計劃納入即將發布的 ServerPod 1.2 版本中的 DevTools 擴充套件程式
Dart Web 和 Wasm 更新
Wasm (也稱為 WebAssembly) 是一種在 Web 瀏覽器上非常棒的新指令格式,還提供可移植、獨立於平台的二進位格式,以適用於現代瀏覽器。我們正在將高階託管語言 (如 Dart) 的垃圾回收功能新增到 Wasm 標準中。從 Chrome 119 開始預設啟用 Wasm 的垃圾回收支援 (也稱為 Wasm-GC)。下一個穩定版本 Firefox 120 也將支援 Wasm-GC。那麼 Dart、Flutter 和 Wasm-GC 現在是什麼情況呢?
Dart-to-Wasm 編譯器幾乎配備所有功能。我們對效能和相容性非常滿意,正在進一步關注邊緣情況,以確保在各種場景中實現暢快執行。
對於 Flutter Web,我們完成了一個新的 “Skwasm” 渲染引擎開發。為了最大限度提高效能,Skwasm 透過 wasm-to-wasm 繫結,將編譯後的應用程式碼直接連線到自定義 CanvasKit Wasm 模組。這是 Flutter Web 多執行緒渲染支援的首次迭代,進一步提高了幀時間。
在採用 Wasm 的 Flutter Web 準備結束目前的實驗狀態之前,我們還有一些事情要做:
- 雙重編譯 : 生成 Wasm 和 JavaScript 輸出,並在執行時啟用功能檢測,以支援具備或不具備 Wasm-GC 支援的瀏覽器。
- 現代 JavaScript 互操作性 : 一種新的基於 擴充套件型別 的 JS 互操作機制,當針對 JavaScript 和 Wasm 時,可以在 Dart 程式碼、瀏覽器 API 和 JS 函式庫之間實現簡潔的、型別安全的呼叫。
- 支援 Wasm 的瀏覽器 API : 新的 package:web,基於現代 JS 互操作機制,取代了 dart:html (及相關函式庫),藉此可輕鬆訪問瀏覽器 API,並且支援在 JS 和 Wasm 目標上使用。
我們正在開始將大量的內部專案遷移到 package:web 和新的 JS 互操作機制,並希望在下一個穩定版本中向你提供更多更新。與此同時,你可以在我們的 WebAssembly 支援 頁面上獲取最新的詳細訊息。
開始體驗
以上就是我們要與你分享的所有內容。Dart 3.2 現已在 dart.dev 中推出,你也可以透過我們將在後續介紹的 Flutter 3.16 版本使用此產品。盡情體驗新版 Dart 吧!