こんにちは。Dartの世界へようこそ。
Dartのコードを書いているとき、もしあなたが画面の前で「if (x != null) …」と何度もタイプしているなら、少し立ち止まってみましょう。
DartのNull安全(Sound Null Safety)は、単なる「エラーを防ぐための足枷」ではありません。これは、コンパイラと開発者が「この値は絶対にNullにならない」という契約を交わすための強力なツールです。
今回は、この契約をエレガントに扱い、冗長なif文を排除して「Dartらしい」コードを書くための秘訣――Null-aware演算子について、その裏側にある思想も含めて解説します。
—
なぜ「Null-aware演算子」を使うのか?
DartのNull安全は、実行時に `NoSuchMethodError` を起こさないよう、コンパイル時にNullの混入を徹底的に弾きます。しかし、現実世界では「値がない(Null)」ことはよくあります。
ここで `if-else` で分岐し続けると、コードは「ガード節」だらけになり、本来やりたかったロジックが見えなくなります。Null-aware演算子は、「Nullである可能性」を言語仕様として組み込み、値を安全かつ簡潔に抽出するための魔法なのです。
—
1. 究極のデフォルト値:`??` (Null-coalescing operator)
「もしNullなら、代わりにこれを使って」という意思表示です。
String? username;
// 冗長な書き方
final name = (username != null) ? username! : ‘ゲスト’;
// Dartらしい書き方
final name = username ?? ‘ゲスト’;
脳内トレース
`??` は左辺を評価します。左辺がNullでないならその値を返し、Nullであれば右辺を返します。これを使えば、初期値の代入や設定値のフォールバックが一行で完了します。
—
2. 存在しないかもしれない場所へのアクセス:`?.` (Null-aware access)
オブジェクトがNullかもしれないとき、`.`(ドット)でアクセスしようとするとコンパイラは即座に警告を出します。そこで `?.` を使います。
class User {
String? email;
}
void main() {
User? user;
// userがNullならエラーにならず、nullを返す
final email = user?.email;
print(email); // null
}
重要な視点
`user?.email` の結果は、`email` が元々 `String` 型であっても、必ず `String?` 型になります。「途中でNullが挟まったら、結果もNullになり得る」というDartの健全な哲学がここにあります。
—
3. 「Nullのときだけ」代入する:`??=` (Null-aware assignment)
変数がまだ初期化されていない(Nullである)ときだけ値を代入したい、というケースは頻繁にあります。
int? count;
// countがNullなら10を代入
count ??= 10;
// すでに値があるなら、代入は無視される
count ??= 20;
print(count); // 10
これはシングルトンパターンや、遅延初期化(Lazy Initialization)の文脈で非常に強力です。
—
現場でやりがちな「落とし穴」
初学者がよく陥る、あるいは現場で見かける「惜しいコード」について少し触れておきましょう。
落とし穴1:`?.` を重ねすぎて読みづらくする
`user?.profile?.settings?.theme` のようにチェーンを繋げすぎるのは要注意です。「どこかでNullが返ってきたらそこから先は処理されない」という挙動は便利ですが、モデルが複雑すぎる証拠かもしれません。設計を見直すサインだと思ってください。
落とし穴2:`!`(強制アンラップ)の乱用
「コンパイラがうるさいから」といって `user!.email` と書くのは、Null安全という契約を破棄する行為です。`!` は「私は今この値がNullではないことを100%保証する(もしNullならアプリをクラッシュさせても構わない)」という宣言です。`!` を使う前に、`??` や `?.` が使えないか必ず一度考えてください。
—
まとめ:Dartを掌握するために
Null-aware演算子は、単にコードを短くするためのテクニックではありません。「値がある状態」と「値がない状態」を型システムの中で美しく共存させるための作法です。
1. `??` でデフォルト値を守る。
2. `?.` で安全に深く潜る。
3. `??=` で賢く初期化する。
これらを使いこなすだけで、あなたの書くコードは驚くほど見通しが良くなり、バグの温床となるif文のネストから解放されます。
ここをクリアできれば、Dartの「Null安全」という強力な武器を、あなたはもう自由に使いこなせているはずです。自信を持って、どんどんコードを書いてみてくださいね!