Flutter2 の List.firstWhere で The return type 'Null' isn't a XXX, as required by the closure's context になる問題
はじめに
ソフトウェアエンジニアの谷藤です。
今回は、タイトルに記載の問題について解説します。
問題の整理
以下のように List の firstWhere を使って特定の値を取り出す際に、値が見つからない場合の throw を防ぐために nullを返す orElse をセットすると、The return type 'Null' isn't a 'String', as required by the closure's context. というエラーが出てしまいます。
final List<String> fruits = ['apple', 'orange', 'banana', 'cherry']; final grape = fruits.firstWhere((fruit) => fruit == 'grape', orElse: () => null); // The return type 'Null' isn't a 'String', as required by the closure's context.
原因
firstWhere のコードを見てみると、List の要素の型と orElse で返す値の型が一致している必要がありました。
E firstWhere(bool test(E element), {E orElse()?}) { for (E element in this) { if (test(element)) return element; } if (orElse != null) return orElse(); throw IterableElementError.noElement(); }
解決方法
collection ライブラリの firstWhereOrNull を使うと素早く解決することができます。 pub.dev
上記のコードを collection を使って変更してみます。
import 'package:collection/collection.dart'; final List<String> fruits = ['apple', 'orange', 'banana', 'cherry']; final grape = fruits.firstWhereOrNull((fruit) => fruit == 'grape');
エラーが出なくなりました。
firstWhereOrNull のコードを見てみると、値が見つからない場合は throw ではなく null を返していることがわかります。
T? firstWhereOrNull(bool Function(T element) test) { for (var element in this) { if (test(element)) return element; } return null; }
さいごに
少しでも参考になったら嬉しいです。
質問やご指摘などがありましたら、コメントにお願いします。
読んでいただきありがとうございました。