0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Dart 自分的!と?の使い方まとめ

0
Last updated at Posted at 2021-09-16

Flutterをやっています。Dartは不可欠です。今回は、DartのNull Safeとか言うややこしいけど多分ものすごく良いものだろう仕組みで使われる、!と?について自分的にまとめてみました。

Null Safeとは?

一時期「ぬるぽ」なる言葉が流行りまして、これはプログラムがNullを指した時にでるメッセージ[Null Pointer]から来たものですが、プログラマーはつねにNullと隣り合わせです。それを解決しようとしたのが、Null Safeですね。ここぐらいまでが、私の頭の限界ですので、とっととまとめます。

次の2つがある

2021年9月30日 コメントでご指摘いただきましたので、以下は実行時に変数を変換しているのでは無くコンパイラに知らせているだけだと追記させていただきます。

1. 絶対Nullじゃないことを前提とした変数や返り値
2. Nullかも知れないことを想定した変数や返り値

これらをそれぞれ変換するには

?:1から2へ
!:2から1へ

つまり

1. 絶対Nullじゃないことを前提とした変数や返り値
   ↑!      ↓?
2. Nullかも知れないことを想定した変数や返り値

と言う具合に変換できます。

?について

宣言

Nullかもしれない変数は、型名の後に?つけます。

int? i;

すると、こうなります。

int nullJanaiyo() {
  return 1;
}

int? nullKamo() {
  return null;
}

main() {
  int keppeki = nullJanaiyo(); //OK
  int? hoge = nullKamo(); //OK

  int keppeki2 = nullKamo(); //Error
  int? hoge2 = nullJanaiyo(); //OK
}

判定

?が2つ。変数判定

?が2つ並んでいるのは、左辺をnullかどうか判定しています。次のような場合に用います。

  int? hoge = null;
  int keppeki = hoge; //Error
  int keppeki2 = hoge ?? 1; //OK
  print(keppeki2); //1がプリントされる

オブジェクトに?. オブジェクト判定

オブジェクトの右に?.をつけることで、オブジェクトがNullでない場合に、.以降のメソッドを実行できます。オブジェクトがnullなら、メソッドは実行されません。

class ItsMe {
  void say() => print("hello");
}

ItsMe nullJanaiyo() {
  return ItsMe();
}

ItsMe? nullKamo() {
  return null;
}

main() {
  ItsMe me = nullJanaiyo();
  ItsMe? who = nullKamo();

  me.say(); //OK。helloがプリントされる
  who.say(); //Error
  who?.say(); //OK。何もプリントされない
}

!について

しっかりしなさい!

変数に!

Nullかも知れない変数は、実は!でNullじゃない変数に変換できます。次の3行目です。

  int? hoge = null;
  print(hoge); //nullがプリントされる
  int keppeki = hoge!; //文法は通る
  print(keppeki); //Error

このように、Nullかも知れない変数の後に!をつけると、Nullじゃない変数になります。ところがNullじゃないと言ったにも関わらずNullだったために、その後のprint文でエラーとなってしまいます。一方初めからNullかも知れないと言っていたhogeは、エラーになっていません。

関数に!

変数同様、関数も!でNullじゃない関数にできます。

class You {
  late Function say;
  late Function? hya;

  setFunction(func) {
    this.say = func;
  }
}

main() {
  You you = You();

  you.setFunction(() => print("Hello"));
  you.say(); //OK
  you.hya(); //文法Error
  you.hya!(); //Error
}

終わりに

以上、自分の理解を深める意味も込めて、ダダダと書いてみました。参考になりましたら幸いです。

0
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?