実行時例外の爆弾を解体せよ:Dartの『List.cast()』とNull安全の深淵
Dartの型システムは、Sound Null Safetyの導入によって劇的に堅牢になりました。しかし、我々が日常的に扱うJSONデータや外部APIからのレスポンス処理において、いまだに「実行時例外」という名の地雷が埋め込まれています。
特に、`List.cast
—
1. なぜ `List.cast()` は危険なのか
多くのエンジニアが犯す過ちは、`List
// 危険:型安全性を破壊する「魔法の呪文」
final rawList = [1, 2, null, 4]; // List
final safeList = rawList.cast
// ここまではエラーにならない
safeList.add(5);
// しかし、後続の処理で `null` にアクセスした瞬間に `TypeError` が発生する
`List.cast
—
2. 実務で推奨される「安全なフィルタリング」パターン
外部APIのレスポンスなど、信頼できないデータソースを扱う場合、`cast` ではなく「データ生成時の厳格なフィルタリング」を行うのが鉄則です。
ベストプラクティス:型指定付きの `whereType()`
Dartの `Iterable` に備わっている `whereType
final List
// 推奨:nullを排除し、指定した型のみを抽出する
// 実行時エラーを未然に防ぐ、最もクリーンな手法
final List
print(cleanList); // [10, 30, 40]
なぜ `whereType` が最強なのか
1. 型ガードの自動適用: `is` 演算子が内部で実行されるため、コンパイラが型を推論し、後続のコードで `null` チェックが不要になります。
2. 計算量の最適化: 一度のイテレーションでフィルタリングと型変換を完結させるため、`cast()` を経由して後から例外を発生させるコストよりも遥かに安上がりです。
—
3. 非同期API連携における「防衛的プログラミング」
WebエンジニアとしてAPI連携を行う際、最も避けるべきは「APIの構造変化でUI全体がクラッシュすること」です。以下のパターンをモジュール化しておくと、大規模開発での強固な基盤となります。
extension SafeListParsing on List
/// null許容のListを、確実に安全なリストに変換する
List
// nullの場合は空リストを返却し、クラッシュを防ぐ
if (this == null) return
// 型安全なフィルタリングを実行
return this!.whereType
}
}
// 使用例
void main() {
final dynamic response = [null, “Apple”, “Banana”, 123];
// 型安全に文字列リストだけを抽出
final List
print(fruits); // [“Apple”, “Banana”]
}
—
4. チーフアーキテクトからの忠告:パフォーマンスとメモリの真実
Dart VMにおいて、`List.cast
一見すると `cast()` のほうがメモリ効率が良さそうに見えますが、「実行時例外を補足するためのコスト」と「バグ調査に費やす開発者の時間」を考慮すれば、`whereType` による生成コストは極めて微々たるものです。
- 小規模なリスト: `whereType` を使い、型安全を優先する。
- 数万件の巨大リスト: そもそもDart側で処理すべきか再考する(API側でフィルタリングさせるか、ストリーム処理を検討する)。
結論
Dartの型システムを掌握するとは、「いつ、どこで型検査を行うか」をコンパイラに任せず、自分自身で制御することです。
`List.cast
型安全とは、単なる規約ではなく、プロダクトを守るための「防壁」です。今日からその防壁を、一段と強固なものにアップデートしてください。