1. ホーム
  2. flutter

[解決済み] DartのNull Safetyとは何ですか?

2023-01-10 01:40:56

質問

Dartの新しいヌル安全言語機能(NNBD)、現在".Transfer.Transfer.Transfer.Transfer.Transferというのがあると聞いたことがあります。 'non-nullable'の実験 というものです。これは、以下のものを導入することになっています。 非ヌル をデフォルトで導入することになっています。 .

機能指定は はここにあります。 また、言語 GitHub の課題はこちら .

どのように動作し、どこで試すことができますか?

どのように解決するのですか?

1. Nullセーフ/Null不可(デフォルト)

null safety / non-nullable (by default)、略して NNBD の機能は、現在 nullsafety.dartpad.dev にあります。 .

を読むことができることに留意してください。 の完全な仕様はこちら 完全なロードマップはこちら . さて、音のヌルヌル安全性は、また Dart のために正式に発表されました。 .


2.1. デフォルトでnon-nullableとはどういう意味ですか?

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

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

上で見たように、変数が NULLでない であり、デフォルトでは というのは、普通に宣言されたすべての変数が はできません。 である null . その結果、代入される前の変数にアクセスする操作は不正となります。

さらに、代入された null を NULL 値でない変数に代入することも禁止されています。

void main() {
  String word;
  
  word = null; // forbidden
  world = 'World!'; // allowed
}

2.1.1. どのように役立つのでしょうか?

もし変数が non-nullable である場合、その変数が決して null . そのため、事前に確認する必要はありません。

int number = 4;

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

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

2.1.2. 記憶する

クラス内のインスタンスフィールド は初期化されなければなりません。 でなければなりません。

class Foo {
  String word; // forbidden

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

参照 late を参照し、この挙動を変更してください。

2.2. Nullable型( ? )

を使用することができます。 nullable 型 は、クエスチョンマークを付加することで ? を付加することで可能です。

class Foo {
  String word; // forbidden

  String? sentence; // allowed
}

A nullable 変数は、使用する前に初期化する必要はありません。初期化されるのは null として初期化されます。

void main() {
  String? word;
  
  print(word); // prints null
}

2.2.2. !

追加する ! を任意の変数 e が投げられます。 ランタイムエラー もし e が NULL であればエラー、そうでなければ NULLでない v .

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
}

2.3. late

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

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

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

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

アクセス方法 word にアクセスすると、ランタイムエラーが発生します。

2.3.1. late final

最終的な変数も遅延マークできるようになりました。

late final int x = heavyComputation();

ここで heavyComputation は一度だけ呼び出されます x がアクセスされたときのみ呼び出されます。さらに late final をイニシャライザなしで宣言することもできます。これは単に late 変数を持つのと同じですが、一度しか代入できません。

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

なお、すべての トップレベル または 静的 初期化子を持つ変数が評価されるようになりました late であっても final .

2.4. 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;

その他の名前付きパラメータは nullable :

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

2.5. ?[]

nullを意識した ?[] 演算子が追加され、インデックス演算子 [] :

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

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

参照 構文決定については、この記事 .

2.5.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);
}


2.6. Never

以下の説明は最低です。読む "上と下" from "ヌルい安全性を理解する" を参考にしてください。

混乱を避けるために:これは開発者が心配するようなことではありません。念のため触れておきたいと思います。

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 は、私の知る限り、プログラマが使うものではないはずです。( は間違っていた ).

3. もっと詳しく

を読むことができます。 サウンドヌルの安全性に関する公式記事 .

さらに、冒頭で述べたように DartPad で遊べます。 .