【Flutter/Dart】オプショナル型をアンラップする

目次

概要

オプショナル型の変数とは、「nullを許容する変数」ということだ。
要は、「何も入っていない状態」というのを設定できるかどうかだ。
逆に、「nullを許容しない」変数を非オプショナル型の変数」という。

変数宣言をする時、null許容をするかどうかを設定することができる。
最近この仕様を取り入れている言語が多い気がする。

C言語などではint型などにnullを入れることはできなかった。
では、代わりにどうなっていたかというと、デフォルト値として(例外もあるが)数値が入る型は「0」、char型など文字列のものは長さ0の文字列(「””」と表現される)が格納されていた。

しかし、最近はnullを許容する型を使えるプログラミング言語が多い。
通常の型(null許容でない型)と書き方も若干異なるので、ここではそれに関して記載していく。

ソースコード

int? elixirCount;
elixirCount = elixirCount! + 1;
if (elixirCount == null) {
  return;
}
elixirCount = elixirCount + 1;

デモ動画

詳細

オプショナル型ってどんなイメージ?

オプショナル型はデータがカプセルに入れられているような状態だ。
中身を取り出さないと計算などに使えない。
中身を取り出す場合は変数名の後ろに「!」をつける。
しかし、中身を取り出す際、その中身が空だった(null)場合、アプリが落ちる。

普通に計算には使えない、使おうとすれば場合によってはアプリが落ちる。
一見少し面倒なように見える。

オプショナル型が無いとどうなるか

ただ、この仕様でいいことがある。今まではデフォルト値として、数字なら0、文字列なら長さ0の文字列が入る。しかし、本当に0を使いたい時と、未設定の場合を区別することができない。
ポケモンやドラクエで考えてみよう。現在の持ち物やアイテムの一覧を見る時、持っていないアイテムに関しては何も表示がされないだろう。
もしも、今までの通りにデフォルトとして「0」を設定してしまうなら、物語序盤の段階で

ロトの剣 0

という感じで表示される。
ポケモンだったらゲーム開始と同時に

マスターボール 0個

なんて表示がされてしまう。ネタバレもいいところだ。

そんな設定されていない変数というものを実現するためにオプショナル型というのは非常に便利だ。

オプショナル型と非オプショナル型は違う

こちらのソースコードを見て欲しい。

elixirCount = elixirCount + 1;

上記のコードが二箇所あるのに、一つ目ではエラーが出て、二つ目ではエラーが出てない。
これはオプショナル型と非オプショナル型の計算は行えないから。

しかし、可能ならnullの可能性も許容したいし、計算にも行いたい。かと言って無理やり中身を取り出すとアプリが落ちる可能性もある。
そこで、if文でnullだった場合に処理を中断する処理を実装しておくことで、条件分岐以下の処理はnullではないことが前提の処理になり、普通の変数のように使える。

if (elixirCount == null) {
  return;
}
// ここ以下がnullでないと保証されている
elixirCount = elixirCount + 1;

Swiftをやっていた人ならguard文と同じような動きをしている。
オプショナル型を使うなら、if文を使ってnullの可能性を潰してから利用しよう!

参考ページ