在空安全镖之前,以下是有效语法:
final list = [1, 2, 3];
final x = list.firstWhere((element) => element > 3, orElse: () => null);
if (x == null) {
// do stuff...
}
现在,firstWhere
需要orElse
返回int
,而不是int?
,因此我不能返回null。
如何从orElse
返回null?
一个方便的函数firstWhereOrNull
解决了这个确切的问题。
导入package:collection
,其中包括对Iterable
的扩展方法。
import 'package:collection/collection.dart';
final list = [1, 2, 3];
final x = list.firstWhereOrNull((element) => element > 3);
if (x == null) {
// do stuff...
}
您不需要外部包,而是可以使用try/catch
int? x;
try {
x = list.firstWhere((element) => element > 3);
} catch(e) {
x = null;
}
要添加到@Alex Hartfords的答案中,对于那些不想仅为此功能导入完整包的人来说,这是您可以添加到应用程序的collection
包中的firstWhereOrNull
的实际实现。
extension FirstWhereExt<T> on List<T> {
/// The first element satisfying [test], or `null` if there are none.
T? firstWhereOrNull(bool Function(T element) test) {
for (final element in this) {
if (test(element)) return element;
}
return null;
}
}
有点晚了,但我想到了这个:
typedef FirstWhereClosure = bool Function(dynamic);
extension FirstWhere on List {
dynamic frstWhere(FirstWhereClosure closure) {
int index = this.indexWhere(closure);
if (index != -1) {
return this[index];
}
return null;
}
}
示例用法:
class Test{
String name;
int code;
Test(code, this.name);
}
Test? test = list.frstWhere(t)=> t.code==123);
另一种选择是将可为null的类型设置为列表。
您编写的不是[1, 2, 3]
,而是<int?>[1, 2, 3]
,使其可以为null。
void main() {
final list = <int?>[1, 2, 3];
final x = list.firstWhere(
(element) => element != null ? (element > 3) : false,
orElse: () => null);
print(x);
}
这应该有效,而且是一个更好的解决方案:
extension IterableExtensions<T> on Iterable<T> {
T? firstWhereOrNull(bool Function(T element) comparator) {
try {
return firstWhere(comparator);
} on StateError catch (_) {
return null;
}
}
}