DartのNull可能性とは何ですか(デフォルトではNull不可能)。


回答:


49

null不可(デフォルト)

null不可(デフォルト)の実験は、現在nullsafety.dartpad.devにあります。ここ仕様全体とロードマップ全体
を読むことができることに注意してください


デフォルトでnull可能でないとはどういう意味ですか?

void main() {
  String word;
  print(word); // illegal

  word = 'Hello, ';
  print(word); // legal
}

上記のように、デフォルトで null可能ではない変数は、通常宣言されているすべての変数をnullにすることができないことを意味しますnull。したがって、変数が割り当てられる前に変数にアクセスする操作はすべて無効です。
さらに、nullnull可能でない変数への代入も許可されていません。

void main() {
  String word;

  word = null; // forbidden
  world = 'World!'; // allowed
}

これはどのように役立ちますか?

変数がnull可能ではない場合、それが絶対にないことを確認できますnull。そのため、事前に確認する必要はありません。

int number = 4;

void main() {
  if (number == null) return; // redundant

  int sum = number + 2; // allowed because number is also non-nullable
}

覚えて

クラスのインスタンスフィールドは、nullにできない場合は初期化する必要があります

class Foo {
  String word; // forbidden

  String sentence = 'Hello, World!'; // allowed
}

lateこの動作を変更するには、以下を参照してください。

null許容型(?

変数の型に疑問符を追加することで、null許容型を使用できます?

class Foo {
  String word; // forbidden

  String? sentence; // allowed
}

NULL可能変数は、使用する前に初期化する必要はありません。nullデフォルトで初期化されます:

void main() {
  String? word;

  print(word); // prints null
}

!

!変数に追加すると、がnullの場合はランタイムエラーeがスローされ、それ以外の場合はnull 不可の値に変換されます。ev

void main() {
  int? e = 5;
  int v = e!; // v is non-nullable; would throw an error if e were null

  String? word;
  print(word!); // throws runtime error if word is null

  print(null!); // throws runtime error
}

late

キーワードlateは、後で初期化される変数をマークするために使用できます。つまり、変数が宣言されたときではなく、アクセスされたときです。これは、後で初期化されるnull不可のインスタンスフィールドを持つことができることも意味します

class ExampleState extends State {
  late String word; // non-nullable

  @override
  void initState() {
    super.initState();

    // print(word) here would throw a runtime error
    word = 'Hello';
  }
}

word初期化される前にアクセスすると、ランタイムエラーがスローされます。

late final

最終変数も遅くマークすることができます:

late final int x = heavyComputation();

ここheavyComputationは一度xアクセスされると呼び出されます。さらに、late final初期化子なしでを宣言することもできます。これは、late変数のみを持つのと同じですが、割り当てることができるのは1回だけです。

late final int x;
// w/e
x = 5; // allowed
x = 6; // forbidden

すべてのことに注意トップレベルまたは静的初期化子を持つ変数は、現在評価されlate、彼らはしている場合に関係なくfinal

required

以前は注釈@required)でしたが、現在は修飾子として組み込まれています。名前付きパラメーター(関数またはクラス用)をとしてマークできるためrequired、nullにできません。

void allowed({required String word}) => null;

これは、パラメーターをnullにできないようにする必要requiredがある場合は、マークするか、デフォルト値を設定する必要があることも意味しています。

void allowed({String word = 'World'}) => null;

void forbidden({int x}) // compile-time error because x can be null (unassigned)
    =>
    null;

他の名前付きパラメーターはnull可能である必要があります。

void baz({int? x}) => null;

?[]

?[]インデックス演算子にnull対応の演算子が追加されました[]

void main() {
  List<int>? list = [1, 2, 3];

  int? x = list?[0]; // 1
}

構文決定に関するこの記事も参照してください。

?..

カスケード演算子には、新しいnull対応演算子もあります?..

次のカスケード操作は、受信者がnullない場合にのみ実行されます。したがって、は?..カスケードシーケンスの最初のカスケード演算子である必要があります。

void main() {
  Path? path;

  // Will not do anything if path is null.
  path
    ?..moveTo(3, 4)
    ..lineTo(4, 3);

  // This is a noop.
  (null as List)
    ?..add(4)
    ..add(2)
    ..add(0);
}

Never

混乱を避けるために、これは開発者が心配する必要のあるものではありません。完全を期すために触れておきたい。

Neverは、で定義されていたNull(存在しないnull)以前のような型になりますdart:core。これらのクラスは両方とも、拡張、実装、または混在させることができないため、使用することを意図していません。

本質的に、Neverタイプは許可されてNeverおらず、それ自体はインスタンス化できないことを意味します。
何もないが、Never中に List<Never>それがあることを意味し、リストの満たすジェネリック型の制約である必要があり、空List<Null>ただし、以下を含めることができますnull

// Only valid state: []
final neverList = <Never>[
  // Any value but Never here will be an error.
  5, // error
  null, // error

  Never, // not a value (compile-time error)
];

// Can contain null: [null]
final nullList = <Null>[
  // Any value but Null will be an error.
  5, // error
  null, // allowed

  Never, // not a value (compile-time error)
  Null, // not a value (compile-time error)
];

例:コンパイラーはを推測List<Never>ます const List<T>
Never私に関する限り、プログラマーによる使用は想定されていません。


5
Never使用できるシナリオをいくつか教えてください。
ラムセスアルダマ

2
null対応のインデックス演算子には、「?。[]」の代わりに「?[]」を使用することを実際に決定しました。後者は文法的には少し複雑ですが、それはユーザーが望んでいることです。
午前

@RamsesAldama何か追加しました。私がリンクした仕様はもっと言及しています。
creativecreatorまたは

@munificent仕様と実験はまだ時代遅れです。ご指摘ありがとうございます。
creativecreatorまたは

1
late finalメンバーまたはインスタンス変数では実行時にのみチェックすることを指摘しておく必要があります。停止の問題のため、開発時またはコンパイル時にそれを確認することはできません。したがって、IDEのヘルプは得られません。
グラハム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.