目錄

遷移至空值安全

本頁說明如何以及何時將您的程式碼遷移至空值安全。以下是遷移您擁有的每個套件的基本步驟

  1. 等待您所相依的套件遷移完成。
  2. 遷移您套件的程式碼,最好是使用互動式遷移工具。
  3. 靜態分析您套件的程式碼。
  4. 測試以確保您的變更有效。
  5. 如果套件已在 pub.dev 上,請以預先發佈版本發佈空值安全版本。

若要非正式地了解使用遷移工具的體驗,請觀看此影片


如何將 Dart 套件遷移至空值安全

1. 等待遷移

#

我們強烈建議依順序遷移程式碼,先遷移相依性圖的葉節點。例如,如果套件 C 相依於套件 B,而套件 B 相依於套件 A,則應先將 A 遷移至空值安全,然後是 B,再是 C。

Illustration of C/B/A sentence

雖然您可以在您的相依性支援空值安全之前遷移,但當您的相依性遷移時,您可能必須變更您的程式碼。例如,如果您預測函式會採用可為空值的參數,但套件將其遷移為不可為空值,則傳遞可為空值的引數會變成編譯錯誤。

本節說明如何在空值安全模式中使用 dart pub outdated 命令來檢查和更新您套件的相依性。這些指示假設您的程式碼在原始碼控制下,以便您輕鬆地復原任何變更。

切換至 Dart 2.19.6 版本

#

切換至 Dart SDK 的 2.19.6 版本。這包含在 Flutter 3.7.12 SDK 中。

檢查您是否擁有 Dart 2.19.6

$ dart --version
Dart SDK version: 2.19.6

檢查相依性狀態

#

使用以下命令取得您套件相依性的遷移狀態

$ dart pub outdated --mode=null-safety

如果輸出顯示所有套件都支援空值安全,則您可以開始遷移。否則,請使用可解析欄位尋找空值安全版本(如果存在)。

以下是一個簡單套件的輸出範例。每個套件的綠色勾選版本都支援空值安全

Output of dart pub outdated

輸出顯示套件的所有相依性都有支援空值安全的可解析預先發佈版本。

如果您的任何套件相依性尚未支援空值安全,我們建議您聯繫套件擁有者。您可以在 pub.dev 上的套件頁面上找到聯絡方式。

更新相依性

#

在遷移您套件的程式碼之前,請將其相依性更新至空值安全版本

  1. 執行 dart pub upgrade --null-safety 以升級至支援空值安全的最新版本。注意:此命令會變更您的 pubspec.yaml 檔案。

  2. 執行 dart pub get

2. 遷移

#

您的程式碼需要成為空值安全的大部分變更都是很容易預測的。例如,如果變數可以為 null,則其類型需要 ? 字尾。如果具名參數不應為可空值,請將其標記為required或給予其預設值

您有兩個遷移選項

使用遷移工具

#

遷移工具會取得一組不具空值安全的 Dart 程式碼,並將其轉換為空值安全。您可以藉由將提示標記新增至您的 Dart 程式碼來引導工具的轉換。

在啟動工具之前,請確保您已準備就緒

  • 使用 Dart SDK 的 2.19.6 版本。
  • 使用 dart pub outdated --mode=null-safety 以確保所有相依性都是空值安全且為最新。

在包含套件 pubspec.yaml 檔案的目錄中執行 dart migrate 命令以啟動遷移工具

$ dart migrate

如果您的套件已準備好遷移,則工具會產生類似以下的一行

View the migration suggestions by visiting:

  http://127.0.0.1:60278/Users/you/project/mypkg.console-simple?authToken=Xfz0jvpyeMI%3D

在 Chrome 瀏覽器中瀏覽該 URL 以查看互動式 UI,您可以在其中引導遷移程序

Screenshot of migration tool

對於每個變數和類型註釋,您可以查看工具推斷的空值性。例如,在前面的螢幕截圖中,工具推斷出第 1 行中的 ints 清單(先前為 int 清單)是可空值的,因此應該是 int? 的清單。

瞭解遷移結果

#

若要查看每個變更(或未變更)的原因,請在「建議編輯」窗格中點擊其行號。原因會顯示在「編輯詳細資訊」窗格中。

例如,考慮以下來自 null 安全性之前的程式碼:

dart
var ints = const <int>[0, null];
var zero = ints[0];
var one = zero + 1;
var zeroOne = <int>[zero, one];

當此程式碼在函式外部時,預設的遷移方式(在函式內部有所不同)是向後相容的,但並非理想的。

dart
var ints = const <int?>[0, null];
var zero = ints[0];
var one = zero! + 1;
var zeroOne = <int?>[zero, one];

點擊「第 3 行」連結,您可以查看遷移工具新增 ! 的原因。因為您知道 zero 不會是 null,所以您可以改善遷移結果。

改善遷移結果

#

當分析推斷出錯誤的可空性時,您可以插入臨時的提示標記來覆寫其建議的編輯。

  • 在遷移工具的「編輯詳細資訊」窗格中,您可以使用「新增 /*?*/ 提示」和「新增 /*!*/ 提示」按鈕插入提示標記。

    這些按鈕會立即在您的檔案中新增註解,並且無法復原。如果您不想要工具插入的提示,可以使用您常用的程式碼編輯器將其移除。

  • 即使工具仍在執行,您也可以使用編輯器來新增提示標記。因為您的程式碼尚未選擇加入 null 安全性,所以您無法使用新的 null 安全性功能。但是,您可以進行不依賴 null 安全性功能變更,例如重構。

    當您完成編輯程式碼後,請點擊「從來源重新執行」以採用您的變更。

下表顯示您可以用來變更遷移工具建議編輯的提示標記。

提示標記對遷移工具的影響
運算式 /!/在遷移後的程式碼中新增 !,將運算式轉換為其底層的不可為 null 的型別。
型別 /!/型別標記為不可為 null。
/*?*//*?*/
將前面的型別標記為可為 null。/*late*/
將變數宣告標記為 late,表示它具有延遲初始化。/*late final*/
將變數宣告標記為 late final,表示它具有延遲的一次性初始化。/*required*/

將參數標記為 required

dart
var zero = ints[0]/*!*/;

單一提示可能會在程式碼的其他地方產生連鎖反應。在之前的範例中,手動在 zero 被賦值的地方(在第 2 行)新增 /*!*/ 標記,會使遷移工具推斷 zero 的型別為 int 而不是 int?。此型別變更可能會影響直接或間接使用 zero 的程式碼。

使用上述提示,遷移工具會變更其建議的編輯,如下列程式碼片段所示。第 3 行的 zero 後面不再有 !,且在第 4 行中,zeroOne 被推斷為 int 的列表,而不是 int?首次遷移
dart
var ints = const <int?>[0, null];
var zero = ints[0];
var one = zero! + 1;
var zeroOne = <int?>[zero, one];
dart
var ints = const <int?>[0, null];
var zero = ints[0]/*!*/;
var one = zero + 1;
var zeroOne = <int>[zero, one];

使用提示的遷移

#

選擇退出檔案

雖然我們建議一次遷移所有內容,但有時這並不實際,尤其是在大型應用程式或套件中。若要選擇退出檔案或目錄,請點擊其綠色核取方塊。稍後,當您套用變更時,每個選擇退出的檔案將保持不變,除了 2.9 版的版本註解

如需有關增量遷移的詳細資訊,請參閱不健全的 null 安全性

請注意,只有完全遷移的應用程式和套件才能與 Dart 3 相容。

#

套用變更

當您對遷移工具建議的所有變更都感到滿意時,請點擊「套用遷移」。遷移工具會刪除提示標記並儲存已遷移的程式碼。該工具也會更新 pubspec 中的最低 SDK 限制,這會讓套件選擇加入 null 安全性。

手動遷移

#

下一步是靜態分析您的程式碼。如果它有效,則測試您的程式碼。然後,如果您已將程式碼發佈到 pub.dev,則發佈 null 安全性預發行版本

如果您不想使用遷移工具,可以手動遷移。

我們建議您先遷移葉節點程式庫,即不從套件匯入其他檔案的程式庫。然後遷移直接依賴葉節點程式庫的程式庫。最後遷移具有最多套件內相依性的程式庫。

例如,假設您有一個 lib/src/util.dart 檔案,它匯入其他(null 安全性)套件和核心程式庫,但沒有任何 import '<local_path>' 指令。請考慮先遷移 util.dart,然後遷移僅依賴 util.dart 的簡單檔案。如果任何程式庫具有循環匯入(例如,A 匯入 B,B 匯入 C,而 C 匯入 A),請考慮一起遷移這些程式庫。

  1. 若要手動遷移套件,請按照下列步驟操作

    編輯套件的 pubspec.yaml 檔案,將最低 SDK 限制設定為至少 2.12.0
    environment:
      sdk: '>=2.12.0 <3.0.0'
  2. yaml

    $ dart pub get

    重新產生套件設定檔

  3. 使用至少 2.12.0 的較低 SDK 限制執行 dart pub get 會將套件中每個程式庫的預設語言版本設定為至少 2.12,使它們全部選擇加入 null 安全性。
    在 IDE 中開啟套件。

  4. 您可能會看到許多分析錯誤。這沒關係。
    使用分析器識別靜態錯誤,遷移每個 Dart 檔案的程式碼。

根據需要新增 ?!requiredlate,消除靜態錯誤。

3. 分析

#

如需有關手動遷移程式碼的更多協助,請參閱不健全的 null 安全性

$ dart pub get
$ dart analyze     # or `flutter analyze`

4. 測試

#

更新您的套件(在 IDE 中或在命令列上使用 dart pub get)。然後使用您的 IDE 或命令列對您的程式碼執行靜態分析

$ dart test       # or `flutter test`

如果您的程式碼通過分析,請執行測試

您可能需要更新期望 null 值的測試。

5. 發佈

#

如果您需要對程式碼進行重大變更,則可能需要重新遷移它。如果是這樣,請在使用遷移工具再次之前,還原您的程式碼變更。

更新套件版本

#

發佈套件。如果您不認為此版本是穩定版本,則將套件發佈為預發行版本

  • 更新套件版本以表示重大變更

  • 如果您的套件已達到 1.0.0 或更高版本,請增加主要版本。例如,如果先前的版本是 2.3.2,則新版本是 3.0.0

檢查您的 pubspec

#

如果您的套件尚未達到 1.0.0增加次要版本將版本更新為 1.0.0。例如,如果先前的版本是 0.3.2,則新版本是 0.4.01.0.0

  • 在發佈穩定 null 安全性版本的套件之前,我們強烈建議您遵循以下 pubspec 規則
  • 將 Dart 的較低 SDK 限制設定為您已測試的最低穩定版本(至少 2.12.0)。

歡迎使用空值安全

#

使用所有直接相依性的穩定版本。

如果您已完成到此步驟,您應該有一個完全遷移、null 安全性的 Dart 套件。

Compiling with sound null safety

如果所有您依賴的套件也已遷移,則您的程式在 null 參考錯誤方面是健全的。當您執行或編譯程式碼時,應該會看到如下的輸出