Dart 3 迁移指南
Dart 3 是一个主要版本,它为 Dart 引入了新的核心功能: 记录 、 模式 和 类修饰符 。
除了这些新功能外,Dart 3 还包含一些可能会破坏现有代码的更改。
本指南将帮助您解决在 升级到 Dart 3 后可能遇到的任何迁移问题。
简介
#未版本化更改与版本化更改
#下面列出的潜在破坏性更改分为两类:
未版本化更改 : 这些更改会影响升级到 Dart 3.0 SDK 或更高版本的任何 Dart 代码。无法“关闭”这些更改。
版本化更改 : 这些更改仅在包或应用程序的语言版本设置为 >= Dart 3.0 时才适用。 语言版本 源自
pubspec.yaml文件 中的sdk下限约束。像这样的 SDK 约束 不会 应用 Dart 3 版本化更改:yamlenvironment: sdk: '>=2.14.0 <3.0.0'但像这样的 SDK 约束会:
yamlenvironment: sdk: '>=3.0.0 <4.0.0'
要使用新的 Dart 3 功能,您必须将语言版本更新到 3.0。这会同时为您提供 Dart 3 版本化更改。
Dart 3 向后兼容性
#许多使用 Dart 2.12 或更高版本的空安全性的包和应用程序可能与 Dart 3 向后兼容。对于 SDK 约束下限为 2.12.0 或更高的任何包,这都是可能的。
Dart 的 pub 工具 允许即使上限限制为低于 3.0.0 的版本也能解析。例如,具有以下约束的包将被允许使用 Dart 3.x SDK 解析,因为当下限约束为 2.12 或更高时,pub 将重新解释上限约束 <3.0.0 为 <4.0.0 :
environment:
sdk: '>=2.14.0 <3.0.0' # 这被解释为 '>=2.14.0 <4.0.0'这允许开发人员在不需要第二次迁移的情况下,使用 Dart 3 健全空安全性以及已经支持 2.12 空安全性的包,除非代码受任何其他 Dart 3 更改的影响。
测试影响
#要了解您的源代码是否受任何 Dart 3 更改的影响,请使用以下步骤:
$ dart --version # 确保这报告 3.0.0 或更高版本。
$ dart pub get # 这应该能够无问题地解析。
$ dart analyze # 这应该能够无错误地通过。如果 pub get 步骤失败,请尝试升级您的依赖项,看看更新的版本是否可能支持 Dart 3:
$ dart pub upgrade
$ dart analyze # 这应该能够无错误地通过。或者,如果需要,还可以包含 主要版本 升级:
$ dart pub upgrade --major-versions
$ dart analyze # 这应该能够无错误地通过。Dart 3 语言更改
#100% 健全空安全性
#Dart 2.12 在两年多前引入了空安全性。在 Dart 2.12 中,用户需要 使用 pubspec 设置 启用空安全性。在 Dart 3 中,空安全性是内置的;您无法将其关闭。
范围
#这是一个 未版本化 更改 ,适用于所有 Dart 3 代码。
症状
#在使用 pub get 解析依赖项时,没有空安全支持的包会引发问题:
$ dart pub get
因为 pkg1 不支持空安全性,所以版本求解失败。
"sdk: '>=2.9.0 <3.0.0'" 的下限必须为 2.12.0 或更高才能启用空安全性。使用 语言版本注释 选择任何低于 2.12 的语言版本的库将导致分析或编译错误:
$ dart analyze .
Analyzing .... 0.6s
error • lib/pkg1.dart:1:1 • 语言版本必须 >=2.12.0。
尝试删除语言版本覆盖并迁移代码。
• illegal_language_version_override$ dart run bin/my_app.dart
../pkg1/lib/pkg1.dart:1:1: Error: 库不支持空安全性。
// @dart=2.9
^^^^^^^^^^^^迁移
#在开始任何迁移到 Dart 3 之前,请确保您的应用程序或包已 100% 迁移以启用空安全性。这需要 Dart 2.19 SDK,而不是 Dart 3 SDK。要了解如何首先迁移您的应用程序或包以支持空安全性,请查看 空安全性迁移指南 。
冒号语法用于默认值
#由于历史原因,命名的可选参数可以使用 : 或 = 指定其默认值。在 Dart 3 中,只允许使用 = 语法。
范围
#这是一个 版本化 更改 ,仅适用于 3.0 或更高版本的语言版本。
症状
#Dart 分析会产生类似这样的错误:
第 2 行 • 不再支持使用冒号作为默认值之前的分隔符。迁移
#从使用冒号更改:
int someInt({int x: 0}) => x;到使用等号:
int someInt({int x = 0}) => x;此迁移可以手动进行,也可以使用 dart fix 自动化:
$ dart fix --apply --code=obsolete_colon_for_default_valuemixin
#在 Dart 3 之前,任何 class 都可以用作 mixin ,只要它没有声明构造函数且超类不是 Object 即可。
在 Dart 3 中,在语言版本 3.0 或更高版本的库中声明的类,除非标记为 mixin ,否则不能用作 mixin。此限制适用于尝试将该类用作 mixin 的任何库中的代码,无论后者的库语言版本如何。
范围
#这是一个 版本化 更改 ,仅适用于 3.0 或更高版本的语言版本。
症状
#类似这样的分析错误:
Mixin 只能应用于类。当既不是 mixin class 也不是 mixin 的类在 with 子句中使用时,分析器会生成此诊断信息。
迁移
#确定该类是否打算用作 mixin。
如果该类定义了一个接口,请考虑使用 implements 。
switch
#Dart 3.0 将 switch 案例解释为 模式 ,而不是常量表达式。
范围
#这是一个 版本化 更改 ,仅适用于 3.0 或更高版本的语言版本。
症状
#在 switch 案例中找到的大多数常量表达式都是具有相同含义的有效模式(命名常量、文字等)。这些将表现相同,不会出现任何症状。
少数不是有效模式的常量表达式将触发 invalid_case_patterns lint 。
迁移
#您可以通过在案例模式前添加 const 来恢复到原来的行为,这样它就不再被解释为模式了:
case const [1, 2]:
case const {'k': 'v'}:
case const {1, 2}:
case const Point(1, 2):您可以使用 dart fix 或 IDE 来快速修复此破坏性更改。
continue
#如果 continue 语句的目标标签不是循环( for 、 do 和 while 语句)或 switch 成员,则 Dart 3 会报告编译时错误。
范围
#这是一个 版本化 更改 ,仅适用于 3.0 或更高版本的语言版本。
症状
#您会看到类似这样的错误:
'continue' 语句中使用的标签必须在循环或 switch 成员上定义。迁移
#如果可以接受更改行为,请更改 continue 以针对有效的带标签语句,该语句必须附加到 for 、 do 或 while 语句。
如果您想保留行为,请将 continue 语句更改为 break 语句。在 Dart 的早期版本中, continue 语句(其目标不是循环或 switch 成员)的行为类似于 break 。
Dart 3 核心库更改
#已移除的 API
#重大更改 #49529 :核心库已被清理,以删除已弃用多年的 API。以下 API 不再存在于 Dart 核心库中。
范围
#这是一个 未版本化 更改 ,适用于所有 Dart 3 代码。
dart:core
#- 移除了已弃用的
List构造函数,因为它不是空安全的。使用列表文字(例如,空列表的[]或空类型列表的<int>[])或List.filled。这只会影响非空安全的代码,因为空安全的代码以前就无法使用此构造函数。 - 移除了
int.parse、double.parse和num.parse上已弃用的onError参数。请改用tryParse方法。 - 移除了已弃用的
proxy和Provisional注解。原始的proxy注解在 Dart 2 中没有效果,Provisional类型和provisional常量仅在 Dart 2.0 开发过程中内部使用。 - 移除了已弃用的
Deprecated.expiresgetter。请改用Deprecated.message。 - 移除了已弃用的
CastError错误。请改用TypeError。 - 移除了已弃用的
FallThroughError错误。在 Dart 2.0 中,以前抛出此错误的穿透类型已成为编译时错误。 - 移除了已弃用的
NullThrownError错误。此错误永远不会从空安全的代码中抛出。 - 移除了已弃用的
AbstractClassInstantiationError错误。在 Dart 2.0 中,调用抽象类的构造函数已成为编译时错误。 - 移除了已弃用的
CyclicInitializationError。在空安全的代码中,不再在运行时检测循环依赖关系。此类代码将以其他方式失败,可能出现 StackOverflowError。 - 移除了已弃用的
NoSuchMethodError默认构造函数。请改用NoSuchMethodError.withInvocation命名构造函数。 - 移除了已弃用的
BidirectionalIterator类。现有的双向迭代器仍然可以工作,它们只是没有共享超类型来将它们锁定到用于向后移动的特定名称。
dart:async
#- 移除了已弃用的
DeferredLibrary类。请改用deferred as导入语法。
dart:developer
#- 移除了已弃用的
MAX_USER_TAGS常量。请改用maxUserTags。 - 移除了已弃用的
Metrics、Metric、Counter和Gauge类,因为自 Dart 2.0 以来它们就已经损坏。
dart:html
#- 正如先前宣布的那样,
Document和HtmlDocument中已弃用的registerElement和registerElement2方法已被删除。有关详细信息,请参见 #49536 。
dart:math
#Random接口只能实现,不能扩展。
dart:io
#- 更新
NetworkProfiling以适应 vm_service:11.0.0 中引入的新Stringid。
症状
#Dart 分析(例如,在您的 IDE 中,或在 dart analyze / flutter analyze 中)将因类似这样的错误而失败:
第 2 行错误 • 未定义类 'CyclicInitializationError'。迁移
#手动迁移以避免使用这些 API。
扩展和实现
#Dart 3 支持新的 类修饰符 ,这些修饰符可以限制类的功能。它们已应用于核心库中的许多类。
范围
#这是一个 版本化 更改 ,仅适用于 3.0 或更高版本的语言版本。
dart:async
#以下声明只能实现,不能扩展:
StreamConsumerStreamIteratorStreamTransformerMultiStreamController
这些声明都没有任何要继承的实现。它们被标记为
interface以表示它们仅作为接口使用。
dart:core
#Function类型不能再被实现、扩展或混合。自 Dart 2.0 以来,为了向后兼容,允许编写implements Function,但它没有任何作用。在 Dart 3.0 中,Function类型是最终的,不能是子类型,防止代码错误地假设它有效。以下声明只能实现,不能扩展:
ComparableExceptionIteratorPatternMatchRegExpRegExpMatchStackTraceStringSink
这些声明都没有任何要继承的实现。它们被标记为
interface以表示它们仅作为接口使用。以下声明不能再被实现或扩展:
MapEntryOutOfMemoryErrorStackOverflowErrorExpandoWeakReferenceFinalizer
MapEntry值类被限制以启用以后的优化。其余类与平台紧密耦合,不打算进行子类化或实现。
dart:collection
#以下接口不能再扩展,只能实现:
Queue
以下实现类不能再实现:
LinkedListLinkedListEntry
以下实现类不能再实现或扩展:
HasNextIterator(也已弃用。)HashMapLinkedHashMapHashSetLinkedHashSetDoubleLinkedQueueListQueueSplayTreeMapSplayTreeSet
Dart 3 工具更改
#已移除的工具
#历史上,Dart 团队提供了一些较小的开发者工具,用于代码格式化( dartfmt )、代码分析( dartanalyzer )等。在 Dart 2.10(2020 年 10 月)中,我们引入了一个新的统一 Dart 开发者工具,即 dart 工具 。
范围
#这是一个 未版本化 更改 ,适用于所有 Dart 3 代码。
症状
#在 Dart 3 中,这些较小的工具不存在,已被新的组合 dart 工具取代。
迁移
#使用 dart 工具中可用的新子命令:
| 历史工具 | dart 替换 | 弃用 | 停止使用 |
|---|---|---|---|
stagehand | dart create | 2.14 | 2.14* |
dartfmt | dart format | 2.14 | 2.15 |
dart2native | dart compile exe | 2.14 | 2.15 |
dart2js | dart compile js | 2.17 | 2.18 |
dartdevc | webdev | 2.17 | 2.18 |
dartanalyzer | dart analyze | 2.16 | 2.18 |
dartdoc | dart doc | 2.16 | 2.17 |
pub | dart pub | 2.15 | 2.17 |
空安全迁移工具
#以下空安全迁移命令已被删除,因为 Dart 3 不支持没有空安全性的代码 :
dart migratedart pub upgrade --null-safetydart pub outdated --mode=null-safety
范围
#这是一个 未版本化 更改 ,适用于所有 Dart 3 代码。
症状
#这些命令将失败。
迁移
#使用 Dart 2.19 迁移到空安全性 。
分析器配置
#启用更严格检查的 分析器配置选项 已更改。
范围
#这是一个 未版本化 更改 ,适用于所有 Dart 3 代码。
症状
#以前的配置选项将失败,并显示类似这样的警告:
选项 'implicit-casts' 不再受支持。
尝试使用新的 'strict-casts' 选项。迁移
#替换分析器配置的这一部分:
analyzer:
strong-mode:
implicit-casts: false
implicit-dynamic: false为:
analyzer:
language:
strict-casts: true
strict-raw-types: true其他工具更改
#- 默认情况下已隐藏已弃用的 Observatory。我们建议使用 DevTools 。
- 命令
dart format fix已被dart fix取代 #1153 。 - SDK 中为 Dart Web 编译器捆绑的快照文件已清理 #50700 。
dart format的输出对于 某些代码 略有更改。- 结束对 Windows 上旧的 pub-cache 位置的向后兼容性。在 Dart 3 之前,
%APPDATA%\Pub\Cache是 pub-cache 的备用位置。从 Dart 3 开始,默认的 pub-cache 位于%LOCALAPPDATA%\Pub\Cache。如果您已将全局激活的包添加到您的PATH,请考虑更新PATH以包含%LOCALAPPDATA%\Pub\Cache\bin。
范围
#这是一个 未版本化 更改 ,适用于所有 Dart 3 代码。
除非另有说明,否则本网站上的文档反映的是 Dart 3.6.0。页面最后更新于 2025-02-05。 查看源代码 或 报告问题.