こんにちは。Dartの深淵へようこそ。
Dartの「Sound Null Safety(健全なNull安全)」は、単なるエラー防止機能ではありません。コンパイラがメモリ上の型を「静的に保証」するための強力な契約です。今回は、多くの開発者が遭遇する「リストからNullを消し去り、非Null型だけを安全に取り出す」という日常的な作業を、Dartの型システムを最大限に活かして攻略する方法を伝授します。
—
1. なぜ「ただのフィルタリング」で躓くのか
例えば、`List
final list =
// 初学者がやりがちなコード
final filtered = list.where((x) => x != null).toList();
これ、動きますよね。でも、コンパイラの視点で見ると「惜しい」んです。`filtered` の型を推論させると、依然として `List
ここで登場するのが、Dartの型システムを裏から操る魔法のメソッド、`whereType
—
2. `whereType` が最強である理由
`whereType
final list =
// 魔法のコード
final safeList = list.whereType
// safeList の型は明確に List
print(safeList); // [1, 3, 5]
なぜこれが「極限の効率」なのか?
1. 型キャストの自動化: `whereType
2. 中間変数の削減: `where` + `map` + `cast` といった複数のステップを踏む必要がありません。これ一つで「フィルタリング」と「型の昇格(Type Promotion)」が同時に完結します。
3. 無駄なNullチェックの排除: この後の処理で `safeList` を扱う際、Dartのコンパイラは「ここにNullが混入する可能性はゼロである」と判断するため、不要な `!` (bang operator) を書く必要がなくなります。
—
3. 現場で陥りやすい「型事故」と回避策
初学者の皆さんがよくやってしまうのが、あえて手動で `cast` を使ってしまうケースです。
// 危険なコードの例
final unsafeList = list.where((x) => x != null).map((x) => x as int).toList();
これを見てください。`as int` という強制キャストを行っていますね。もし将来的にリストの中身が複雑になったとき、この `as` は実行時のクラッシュ(TypeError)の原因になります。
`whereType
—
4. 脳内トレース:メモリとIsolateの視点
少しだけ深い話をしましょう。Dartのリストは、メモリ上で連続した領域を確保しようと試みます。`List
`whereType
—
まとめ:ここをクリアすれば、もう怖くない!
Null安全とは、単にコードを複雑にするルールではありません。「コンパイラという優秀なパートナーと、コードの安全性を共有する契約」です。
- `where()` + `!= null`: フィルタリングはできるが、型は昇格しない。
- `whereType
()` : フィルタリングと同時に、その後の処理に必要な「型」を保証する。
これからは、リストの中の「Nullの影」を追い払うとき、迷わず `whereType
Dartの型システムは、使いこなせばこれほど頼もしい武器はありません。また次のステップで、さらに深い深淵を覗いていきましょう。応援していますよ!