摘要

#

本遷移指南說明如何將使用多個 of 靜態存取器及相關存取器上的 nullOk 參數的程式碼,轉換為使用回傳可為 null 的替代 API。

背景

#

Flutter 常見的一種模式,是允許透過靜態成員函式來查找某些類型的元件(InheritedWidgets),這些函式通常命名為 of,並接受一個 BuildContext

在 non-nullability(非空安全)尚未成為預設之前,這些 API 提供一個切換開關,能夠在元件樹中找不到該元件時,選擇是拋出例外還是回傳 null。這樣的設計很實用,也不會造成混淆,因為當時每個變數都可以是 nullable。

當 non-nullability 成為預設後,讓最常用的 API 回傳 non-nullable 值就變得更理想。因為如果呼叫 MediaQuery.of(context, nullOk: false) 後,仍然需要加上 ! 運算子,或是 ? 並加上預設值,這樣的寫法顯得不自然。

nullOk 參數原本是一種簡便的 null safety 切換方式,但隨著語言本身支援 non-nullability,這個參數就變得多餘,甚至可能給開發者帶來矛盾的訊息。

為了解決這個問題,of 存取器(以及其他也使用 nullOk 的相關存取器)被拆分為兩種呼叫方式:一種回傳 non-nullable 值,若找不到目標元件則拋出例外;另一種則回傳可為 null 的值,不會拋出例外,找不到元件時回傳 null。

本變更的設計文件請參考 Eliminating nullOk parameters

變更說明

#

實際的變更是將這些 API 移除 nullOk 參數,並改為回傳 non-nullable 值:

並同時新增以下這些 API,讓其回傳可為 null 的值:

遷移指南

#

為了讓你的程式碼改用新的 API 形式,請將所有帶有 nullOk = true 參數的呼叫,改為使用 maybe 形式的 API。

也就是說,原本這樣的寫法:

dart
MediaQueryData? data = MediaQuery.of(context, nullOk: true);

變更為:

dart
MediaQueryData? data = MediaQuery.maybeOf(context);

你也需要修改所有使用 nullOk = false(通常為預設值)呼叫 API 的情境,以接受不可為 null 的回傳值,或移除任何 ! 運算子:

所以可以選擇以下任一方式:

dart
MediaQueryData data = MediaQuery.of(context)!; // nullOk false by default.
MediaQueryData? data = MediaQuery.of(context); // nullOk false by default.

兩者都變成:

dart
MediaQueryData data = MediaQuery.of(context); // No ! or ? operator here now.

unnecessary_non_null_assertion 分析選項在尋找應移除 ! 運算子的地方時非常有幫助,而 unnecessary_nullable_for_final_variable_declarations 分析選項則有助於找出在 finalconst 變數上不必要的問號運算子。

時程表

#

合併於版本:1.24.0

正式版釋出:2.0.0

參考資料

#

API 文件:

相關議題:

相關 PR: