💬

[Dart]NullSafetyの個人的まとめ(基礎部分)

2022/07/02に公開

NullSafetyとは

「NullSafety」とは簡単に言うと、
「null値を許容するときと許容しない時の方針を定めたもの(ルール)」。
Flutter2.0から導入されたnullによるエラーを防ぐルール・仕組みのこと

また、「null」とは
空っぽ(な変数の箱)」って感じ。

デフォルトではどうなってるの?

NullSafetyが適用されている場合(flutter2.0以降はデフォルトで適用されている)、
int numberって宣言した変数numbernullを代入したら、エラーが出るようになっている。(この状態を"NullSafetyがオンになっている"とかって言う)

言い換えると、普通にintと宣言したのでは「non-nullable(Nullだめです)」と言って、「Null型を受付ません!」と言ってる事になり、エラーが出る。(これこそNullSafetyのしくみ。)
NullSafetyを解除すると、numberにnullを代入しても問題なく通る(NullSafetyが無く「nullable(nullでもオケっす!)」と呼ばれる状態になる)。

ここまでまとめると、

  • デフォルトは変数宣言時:non-nullable(null受け付けません)
  • 解除し、NullSafetyがOFF:nullable(nullでもおk。エラーでません)

nullable(null許容)にしたいな〜〜って時

nullを許容して変数宣言したいな!って時はint? numberって感じで「型名? 変数名」で宣言する。

NullSafetyの例

1. 一つ目の例 (if (y != null){} でnullを分別してる)

main.dart
import "dart:math" as math;
class NullSample {
  method1() {
    int x = 10; // ①nullの可能性はない
    int? y = getNullable(); // ②nullの可能性がある
   
    //x = y; // Non-NullableにNullableを入れるのはコンパイルエラー
    //y = x; // NullableにNon-Nullableを入れるのはOK

    if (y != null) {//nullならXをYで上書き。nullじゃ無いならこの文は無視でxが出力
      x = y; //nullチェックの後のためコンパイルOK(yとxの集合が完全一致する)
    }     //つまりnullチェックによってYの集合がXの集合まで重なるイメージ。

  }
  //ランダムでnullか1を返すメソッド
  getNullable() {
    var rand = new math.Random();
    if (rand.nextInt(2) == 0) {
      return null;
    }
    return 1;
  }
}

Point

  1. ①の変数 x は?付いて無いのでnon-nullable(null禁止)
  2. ②の変数 y は?ついているのでnullable(nullおけ)

(yの方がxより集合が大きいイメージ!)
集合の図
アウトプットは以下

I/flutter ( 7785): x: 1 y: 1 (1が返る場合)
I/flutter ( 7785): x: 10 y: null (Nullが返る場合)
  • nullならXをYで上書き。nullじゃ無いならこの文は無視でxが出力
  • //nullチェックの後のためコンパイルOK(yとxの集合が完全一致する)

2. 二つ目の例 ( x = y!; の記述の部分でyがエラーならコンパイルエラーを起こさせる)

main.dart
import "dart:math" as math;
class NullSample {
  method2() {
    int x = 20; // nullではない
    int? y = getNullable();; // Nullの可能性がある
    // NonNullableにキャストして代入する。
    // ただし、yにnullが入った状態で行うとエラーになるので注意
    x = y!;
    print("x: " + x.toString() + " y: " + y.toString());
  }
  getNullable() {
    var rand = new math.Random();
    if (rand.nextInt(2) == 0) {
      return null;
    }
    return 1;
  }
}

Point

  • x = y!; => 「yをxに代入します!(y!="yはnullだめ!nullならエラー!")」って感じ
    アウトプットは以下。
    コンパイルエラーを起こさなければ上段、起こせば下段のように返す。
I/flutter ( 7785): x: 1 y: 1(1が返る場合)

════════ Exception caught by gesture library ═══════════════════════════════════
type 'Null' is not a subtype of type 'String' of 'function result'
════════════════════════════════════════════════════════════════════════════════
 (Nullが返る場合)

以上です。間違えが見つかり次第、或いは知識がアップデートされ次第改訂していきます。🙏

参考記事

GitHubで編集を提案

Discussion