Dart 3 遷移指南
Dart 3 是一個主要版本,為 Dart 引入了新的核心功能:records、patterns 和 class modifiers。
除了這些新功能之外,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' # This is interpreted as '>=2.14.0 <4.0.0'這使得開發者可以使用 Dart 3 健全的空安全與已經支援 2.12 空安全的包一起工作,而無需第二次遷移,除非程式碼受到其他任何 Dart 3 變更的影響。
測試影響
#要了解您的原始碼是否受到任何 Dart 3 變更的影響,請使用以下步驟
dart --version # Make sure this reports 3.0.0 or higher.
dart pub get # This should resolve without issues.
dart analyze # This should pass without errors.如果 pub get 步驟失敗,請嘗試升級您的依賴項,看看是否有更新的版本可能支援 Dart 3
dart pub upgrade
dart analyze # This should pass without errors.或者,如果需要,也包括 主要版本 的升級
dart pub upgrade --major-versions
dart analyze # This should pass without errors.Dart 3 語言變更
#100% 健全的空安全
#Dart 2.12 在兩年多前引入了空安全。在 Dart 2.12 中,使用者需要透過 pubspec 設定啟用空安全。在 Dart 3 中,空安全是內建的;您無法將其關閉。
範圍
#這是無版本控制變更,適用於所有 Dart 3 程式碼。
症狀
#未開發支援空安全的包在使用 pub get 解析依賴項時會引起問題
dart pub get
Because pkg1 doesn't support null safety, version solving failed.
The lower bound of "sdk: '>=2.9.0 <3.0.0'" must be 2.12.0 or higher to enable null safety.使用語言版本註釋選擇低於 2.12 任何語言版本而選擇不使用空安全的庫將導致分析或編譯錯誤
dart analyze .
Analyzing .... 0.6s
error • lib/pkg1.dart:1:1 • The language version must be >=2.12.0.
Try removing the language version override and migrating the code.
• illegal_language_version_overridedart run bin/my_app.dart
../pkg1/lib/pkg1.dart:1:1: Error: Library doesn't support null safety.
// @dart=2.9
^^^^^^^^^^^^遷移
#在開始任何 Dart 3 遷移之前,請確保您的應用或包已 100% 遷移以啟用空安全。這需要 Dart 2.19 SDK,而不是 Dart 3 SDK。要了解如何首先將您的應用或包遷移以支援空安全,請查閱空安全遷移指南。
預設值的冒號語法
#出於歷史原因,命名的可選引數可以使用 : 或 = 來指定其預設值。在 Dart 3 中,只允許使用 = 語法。
範圍
#這是有版本控制變更,僅適用於語言版本 3.0 或更高版本。
症狀
#Dart 分析會產生類似如下錯誤
line 2 • Using a colon as a separator before a default value is no longer supported.遷移
#將冒號用法改為
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,否則不能用作 mixins。此限制適用於任何嘗試將該類用作 mixin 的庫中的程式碼,而不管後者的語言版本如何。
範圍
#這是有版本控制變更,僅適用於語言版本 3.0 或更高版本。
症狀
#類似如下的分析錯誤
Mixin can only be applied to class.當一個既不是 mixin class 也不是 mixin 的類用於 with 子句時,分析器會生成此診斷資訊。
遷移
#確定該類是否打算用作 mixin。
如果該類定義了一個介面,請考慮使用 implements。
switch
#Dart 3.0 將 switch case 解釋為 模式 而不是常量表達式。
範圍
#這是有版本控制變更,僅適用於語言版本 3.0 或更高版本。
症狀
#switch case 中找到的大多數常量表達式都是具有相同含義的有效模式(命名常量、字面量等)。這些將行為相同,不會出現任何症狀。
少數不是有效模式的常量表達式將觸發 invalid_case_patterns lint。
遷移
#您可以透過在 case 模式前加上 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 或更高版本。
症狀
#您將看到類似如下的錯誤
The label used in a 'continue' statement must be defined on either a loop or a switch member.遷移
#如果改變行為是可接受的,將 continue 更改為指向有效的帶標籤語句,該語句必須附加到 for、do 或 while 語句。
如果您想保留行為,將 continue 語句更改為 break 語句。在 Dart 的早期版本中,未指向迴圈或 switch 成員的 continue 語句行為類似於 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錯誤。之前丟擲此錯誤的fall-through型別在 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 中引入的新的Stringids
症狀
#Dart 分析(例如在您的 IDE 中,或在 dart analyze/flutter analyze 中)將失敗並出現類似如下錯誤
error line 2 • Undefined class 'CyclicInitializationError'.遷移
#手動遷移,停止使用這些 API。
Extends 與 implements
#Dart 3 支援新的類修飾符,可以限制類的能力。它們已應用於核心庫中的許多類。
範圍
#這是有版本控制變更,僅適用於語言版本 3.0 或更高版本。
dart:async
#以下宣告只能實現,不能擴充套件
StreamConsumerStreamIteratorStreamTransformerMultiStreamController
這些宣告都不包含任何可繼承的實現。它們被標記為
interface,表示它們僅 intended 作為介面。
dart:core
#Function型別不能再被實現、擴充套件或混入。自 Dart 2.0 起,出於向後相容性,允許編寫implements Function,但它沒有產生任何效果。在 Dart 3.0 中,Function型別是 final 的,不能被子型別化,防止程式碼錯誤地認為它有效。以下宣告只能實現,不能擴充套件
ComparableExceptionIteratorPatternMatchRegExpRegExpMatchStackTraceStringSink
這些宣告都不包含任何可繼承的實現。它們被標記為
interface,表示它們僅 intended 作為介面。以下宣告不能再被實現或擴充套件
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 程式碼。
症狀
#以前的配置選項將失敗並出現類似如下警告
The option 'implicit-casts' is no longer supported.
Try using the new 'strict-casts' option.遷移
#替換分析器配置的這一部分
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 程式碼。