移除 nullOk 參數
為了提升 API 在 null safety 環境下的清晰度,移除 nullOk 參數。
摘要
#
本遷移指南說明如何將使用多個 of 靜態存取器及相關存取器上的 nullOk
參數的程式碼,轉換為使用回傳可為 null 的替代 API。
背景
#
Flutter 常見的一種模式,是允許透過靜態成員函式來查找某些類型的元件 (Widget)
(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 值:
MediaQuery.ofNavigator.of-
ScaffoldMessenger.of Scaffold.ofRouter.of-
Localizations.localeOf -
FocusTraversalOrder.of -
FocusTraversalGroup.of Focus.ofShortcuts.of-
Actions.handler Actions.find-
Actions.invoke -
AnimatedList.of -
SliverAnimatedList.of -
CupertinoDynamicColor.resolve -
CupertinoDynamicColor.resolveFrom -
CupertinoUserInterfaceLevel.of -
CupertinoTheme.brightnessOf -
CupertinoThemeData.resolveFrom -
NoDefaultCupertinoThemeData.resolveFrom -
CupertinoTextThemeData.resolveFrom -
MaterialBasedCupertinoThemeData.resolveFrom
並同時新增以下這些 API,讓其回傳可為 null 的值:
-
MediaQuery.maybeOf -
Navigator.maybeOf -
ScaffoldMessenger.maybeOf -
Scaffold.maybeOf -
Router.maybeOf -
Localizations.maybeLocaleOf -
FocusTraversalOrder.maybeOf -
FocusTraversalGroup.maybeOf Focus.maybeOfShortcuts.maybeOf-
Actions.maybeFind -
Actions.maybeInvoke -
AnimatedList.maybeOf -
SliverAnimatedList.maybeOf -
CupertinoDynamicColor.maybeResolve -
CupertinoUserInterfaceLevel.maybeOf -
CupertinoTheme.maybeBrightnessOf
遷移指南
#
為了讓你的程式碼改用新的 API 形式,請將所有帶有 nullOk = true 參數的呼叫,
改為使用 maybe 形式的 API。
也就是說,原本這樣的寫法:
MediaQueryData? data = MediaQuery.of(context, nullOk: true);
變更為:
MediaQueryData? data = MediaQuery.maybeOf(context);
你也需要修改所有使用 nullOk = false(通常為預設值)呼叫 API 的情境,以接受不可為 null 的回傳值,或移除任何
! 運算子:
所以可以選擇以下任一方式:
MediaQueryData data = MediaQuery.of(context)!; // nullOk false by default.
MediaQueryData? data = MediaQuery.of(context); // nullOk false by default.
兩者都變成:
MediaQueryData data = MediaQuery.of(context); // No ! or ? operator here now.
unnecessary_non_null_assertion 分析選項在尋找應移除 ! 運算子的地方時非常有幫助,而 unnecessary_nullable_for_final_variable_declarations
分析選項則有助於找出在 final 和 const 變數上不必要的問號運算子。
時程表
#
合併於版本:1.24.0
正式版釋出:2.0.0
參考資料
#API 文件:
MediaQuery.ofNavigator.of-
ScaffoldMessenger.of Scaffold.ofRouter.of-
Localizations.localeOf -
FocusTraversalOrder.of -
FocusTraversalGroup.of Focus.ofShortcuts.of-
Actions.handler Actions.find-
Actions.invoke -
AnimatedList.of -
SliverAnimatedList.of -
CupertinoDynamicColor.resolve -
CupertinoDynamicColor.resolveFrom -
CupertinoUserInterfaceLevel.of -
CupertinoTheme.brightnessOf -
CupertinoThemeData.resolveFrom -
NoDefaultCupertinoThemeData.resolveFrom -
CupertinoTextThemeData.resolveFrom -
MaterialBasedCupertinoThemeData.resolveFrom -
MediaQuery.maybeOf -
Navigator.maybeOf -
ScaffoldMessenger.maybeOf -
Scaffold.maybeOf -
Router.maybeOf -
Localizations.maybeLocaleOf -
FocusTraversalOrder.maybeOf -
FocusTraversalGroup.maybeOf Focus.maybeOfShortcuts.maybeOf-
Actions.maybeFind -
Actions.maybeInvoke -
AnimatedList.maybeOf -
SliverAnimatedList.maybeOf -
CupertinoDynamicColor.maybeResolve -
CupertinoUserInterfaceLevel.maybeOf -
CupertinoTheme.maybeBrightnessOf
相關議題:
相關 PR:
-
Remove
nullOkinMediaQuery.of -
Remove
nullOkinNavigator.of -
Remove
nullOkparameter fromAnimatedList.ofandSliverAnimatedList.of -
Remove
nullOkparameter fromShortcuts.of,Actions.find, andActions.handler -
Remove
nullOkparameter fromFocus.of,FocusTraversalOrder.of, andFocusTraversalGroup.of -
Remove
nullOkparameter fromLocalizations.localeOf -
Remove
nullOkparameter fromRouter.of -
Remove
nullOkfromScaffold.ofandScaffoldMessenger.of -
Remove
nullOkparameter from Cupertino color resolution APIs -
Remove vestigial
nullOkparameter fromLocalizations.localeOf -
Remove
nullOkfromActions.invoke, addActions.maybeInvoke
Unless stated otherwise, the documentation on this site reflects Flutter 3.44.0. Page last updated on 2026-06-14. View source or report an issue.