移除 nullOk 参数
概述
#本迁移指南描述了如何将使用多个 of
静态访问器及相关访问器上的 nullOk
参数的代码,转换为使用具有可空返回值的备用 API。
背景
#Flutter 中有一种常见的模式,即允许使用静态成员函数(通常称为 of
)来查找某些类型的 widget(InheritedWidget
),这些函数需要一个 BuildContext
。
在非空性成为默认设置之前,这些 API 上有一个开关很有用,可以在 widget 不存在于 widget 树中时抛出异常,或者在未找到 widget 时返回 null。这很有用,而且不令人困惑,因为当时每个变量都是可空的。
当非空性成为默认设置后,就希望最常用的 API 返回一个非空值。这是因为调用 MediaQuery.of(context, nullOk: false)
,然后在此调用后仍然需要一个 !
运算符或 ?
和一个回退值,感觉很不方便。
nullOk
参数是一种廉价的提供空安全切换方式,但在真正的语言支持非空性的大环境下,它却向开发者提供了冗余甚至可能矛盾的信号。
为了解决这个问题,of
访问器(以及一些也使用 nullOk
的相关访问器)被拆分成了两个调用:一个返回非空值,并在找不到所需 widget 时抛出异常;另一个返回可空值,不抛出异常,并在找不到 widget 时返回 null。
此变更的设计文档是 移除 nullOk 参数。
变更说明
#实际的变更修改了这些 API,使其不再具有 nullOk
参数,并返回非空值
MediaQuery.of
Navigator.of
ScaffoldMessenger.of
Scaffold.of
Router.of
Localizations.localeOf
FocusTraversalOrder.of
FocusTraversalGroup.of
Focus.of
Shortcuts.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,用于返回可空值
MediaQuery.maybeOf
Navigator.maybeOf
ScaffoldMessenger.maybeOf
Scaffold.maybeOf
Router.maybeOf
Localizations.maybeLocaleOf
FocusTraversalOrder.maybeOf
FocusTraversalGroup.maybeOf
Focus.maybeOf
Shortcuts.maybeOf
Actions.maybeFind
Actions.maybeInvoke
AnimatedList.maybeOf
SliverAnimatedList.maybeOf
CupertinoDynamicColor.maybeResolve
CupertinoUserInterfaceLevel.maybeOf
CupertinoTheme.maybeBrightnessOf
迁移指南
#为了修改代码以使用新形式的 API,请将所有包含 nullOk = true
作为参数的 API 调用,转换为使用 API 的 maybe
版本。
所以,这个
MediaQueryData? data = MediaQuery.of(context, nullOk: true);
变成了
MediaQueryData? data = MediaQuery.maybeOf(context);
您还需要修改所有使用 nullOk = false
(通常是默认值)调用 API 的实例,以接受非空返回值,或移除任何 !
运算符
所以,以下两者之一
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.of
Navigator.of
ScaffoldMessenger.of
Scaffold.of
Router.of
Localizations.localeOf
FocusTraversalOrder.of
FocusTraversalGroup.of
Focus.of
Shortcuts.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.maybeOf
Shortcuts.maybeOf
Actions.maybeFind
Actions.maybeInvoke
AnimatedList.maybeOf
SliverAnimatedList.maybeOf
CupertinoDynamicColor.maybeResolve
CupertinoUserInterfaceLevel.maybeOf
CupertinoTheme.maybeBrightnessOf
相关议题
相关 PR
- 移除
MediaQuery.of
中的nullOk
- 移除
Navigator.of
中的nullOk
- 从
AnimatedList.of
和SliverAnimatedList.of
中移除nullOk
参数 - 从
Shortcuts.of
、Actions.find
和Actions.handler
中移除nullOk
参数 - 从
Focus.of
、FocusTraversalOrder.of
和FocusTraversalGroup.of
中移除nullOk
参数 - 从
Localizations.localeOf
中移除nullOk
参数 - 从
Router.of
中移除nullOk
参数 - 从
Scaffold.of
和ScaffoldMessenger.of
中移除nullOk
- 从 Cupertino 颜色解析 API 中移除
nullOk
参数 - 从
Localizations.localeOf
中移除遗留的nullOk
参数 - 从
Actions.invoke
中移除nullOk
,并添加Actions.maybeInvoke