Dart List的firstWhere等方法空安全下缺失元素返回null方案咨询
Dart空安全下列表查询返回空的解决方案
不需要为每个类型定义null替代值,有以下三种通用方案可以实现列表查询匹配不到元素时直接返回null,无需修改原有非空列表的类型声明:
方案1:使用firstWhereOrNull系列扩展方法(最推荐)
Dart 3.0及以上版本已在dart:collection中内置了Iterable的扩展方法,包含firstWhereOrNull、singleWhereOrNull、lastWhereOrNull三类,返回值类型天然为E?,匹配不到元素时自动返回null:
import 'dart:collection'; void main() { List<String> strList = ['apple', 'banana', 'cherry']; // 匹配到返回对应字符串,匹配不到返回null,原列表始终保持List<String>类型 String? target = strList.firstWhereOrNull((element) => element == 'orange'); print(target); // 输出null }
如果项目使用的Dart版本低于3.0,可手动定义全局扩展方法,一次实现全项目通用:
extension NullableWhereExtension<E> on Iterable<E> { E? firstWhereOrNull(bool Function(E element) test) { for (final element in this) { if (test(element)) return element; } return null; } E? lastWhereOrNull(bool Function(E element) test) { E? matched; var found = false; for (final element in this) { if (test(element)) { matched = element; found = true; } } return found ? matched : null; } E? singleWhereOrNull(bool Function(E element) test) { E? matched; var matchCount = 0; for (final element in this) { if (test(element)) { matched = element; matchCount++; if (matchCount > 1) return null; } } return matchCount == 1 ? matched : null; } }
方案2:局部泛型转换
不需要修改整个列表的泛型声明,仅在调用查询方法时做单次类型转换即可:
List<String> strList = ['apple', 'banana', 'cherry']; // 仅临时将当前迭代器转为String?类型,不影响原列表的非空约束 String? target = strList.cast<String?>().firstWhere( (element) => element == 'orange', orElse: () => null, );
方案3:异常捕获(仅适合低频调用场景)
也可以通过捕获firstWhere匹配不到时抛出的StateError实现返回null的效果,不过异常捕获有额外性能开销,不建议在高频循环逻辑中使用:
List<String> strList = ['apple', 'banana', 'cherry']; String? target; try { target = strList.firstWhere((element) => element == 'orange'); } on StateError { target = null; }
内容的提问来源于stack exchange,提问作者Marcin Wróblewski
相关产品推荐
相关产品推荐

