目次

サウンドヌルセーフティ

Dart言語は、サウンドヌルセーフティを強制します。

ヌルセーフティは、意図しない`null`に設定された変数へのアクセスによって発生するエラーを防ぎます。

たとえば、メソッドが整数を期待しているのに`null`を受け取ると、アプリはランタイムエラーを引き起こします。この種のエラー(ヌルデリファレンスエラー)は、デバッグが困難な場合があります。

サウンドヌルセーフティでは、すべての変数に値が必要です。つまり、Dartはすべての変数を*ヌル許容ではない*とみなします。宣言された型の値のみを代入できます(例:`int i=42`)。デフォルトの変数型には`null`を代入することはできません。変数型に`null`値を含めることができるようにするには、型注釈の後に`?`を追加します:`int? i`。これらの特定の型には、`null`または定義された型の値のいずれかを含めることができます。

サウンドヌルセーフティは、潜在的な**ランタイムエラー**を**編集時**の解析エラーに変更します。ヌルセーフティを使用すると、Dartアナライザーとコンパイラは、ヌル許容ではない変数に次のいずれかの状態がある場合にフラグを立てます。

  • ヌル以外の値で初期化されていない
  • `null`値が代入されている

これらのチェックにより、アプリをデプロイする*前*にこれらのエラーを修正できます。

例による導入

#

ヌルセーフティでは、次のコードの変数のいずれも`null`にはなりません。

dart
// With null safety, none of these can ever be null.
var i = 42; // Inferred to be an int.
String name = getFileName();
final b = Foo();

変数が`null`値を持つ可能性があることを示すには、型宣言に`?`を追加するだけです。

dart
int? aNullableInt = null;

ヌルセーフティの原則

#

Dartは、次の2つのコア設計原則を使用してヌルセーフティをサポートしています。

  • **デフォルトでヌル許容ではない**。変数がヌルになる可能性があることを明示的にDartに指示しない限り、ヌル許容ではないとみなされます。このデフォルトは、ヌル許容ではない方がAPIで圧倒的に一般的な選択肢であるという調査結果に基づいて選択されました。

  • **完全にサウンド**。Dartのヌルセーフティはサウンドであるため、コンパイラの最適化が可能になります。型システムによって何かがヌルではないと判断された場合、そのものは*決して*ヌルになることはありません。プロジェクト全体とその依存関係をヌルセーフティに移行すると、サウンドネスのメリットを最大限に享受できます。バグの減少だけでなく、バイナリのサイズ縮小と実行速度の向上も期待できます。

Dart 3とヌルセーフティ

#

Dart 3には、サウンドヌルセーフティが組み込まれています。Dart 3では、サウンドヌルセーフティがないコードの実行が禁止されています。

Dart 3への移行方法については、Dart 3移行ガイドを参照してください。ヌルセーフティサポートがないパッケージは、依存関係の解決時に問題を引き起こします。

$ 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.

Dart 3と互換性のないライブラリは、解析エラーまたはコンパイルエラーの原因となります。

$ 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_override
$ dart run bin/my_app.dart
../pkg1/lib/pkg1.dart:1:1: Error: Library doesn't support null safety.
// @dart=2.9
^^^^^^^^^^^^

これらの問題を解決するには

  1. pub.devからインストールしたパッケージのヌルセーフバージョンを確認してください。
  2. 移行するすべてのソースコードをサウンドヌルセーフティを使用するように移行します。

Dart 3は、DartとFlutterの安定チャネルで利用できます。詳細については、ダウンロードページを参照してください。Dart 3互換性をテストするには、Dart 3以降を使用してください。

$ dart --version                     # make sure this reports 3.0.0-417.1.beta or higher
$ dart pub get / flutter pub get     # this should resolve without issues
$ dart analyze / flutter analyze     # this should pass without errors

`pub get`ステップが失敗した場合は、依存関係の状態を確認してください。

`analyze`ステップが失敗した場合は、アナライザーによってリストされた問題を解決するためにコードを更新してください。

Dart 2.xとヌルセーフティ

#

Dart 2.12から2.19までは、ヌルセーフティを有効にする必要があります。Dart 2.12より前のSDKバージョンでは、ヌルセーフティを使用できません。

サウンドヌルセーフティを有効にするには、SDK制約の下限を2.12以降の言語バージョンに設定します。たとえば、`pubspec.yaml`ファイルには次の制約がある場合があります。

yaml
environment:
  sdk: '>=2.12.0 <3.0.0'

既存コードの移行

#

ヌルセーフティサポートなしで記述されたDartコードは、ヌルセーフティを使用するように移行できます。Dart SDKバージョン2.12から2.19に含まれる`dart migrate`ツールを使用することをお勧めします。

$ cd my_app
$ dart migrate

コードをヌルセーフティに移行する方法については、移行ガイドを参照してください。

詳細情報

#

ヌルセーフティの詳細については、次のリソースを参照してください。