有趣的问题。我真的没有一个很好的答案,但这是我现在能想到的最好的答案。
第一个解决方案是这可能不是最有效的方法,因为我们正在正确地创建一个新的列表对象:
void main() {
final Map<String, Iterable<int>> map = {};
for (final value in [...?map['test']]) {
// Do something with value
}
}
更有效但也更长的是:
void main() {
final Map<String, Iterable<int>> map = {};
for (final value in map['test'] ?? const <int>[]) {
// Do something with value
}
}
最好的解决方案可能是像这样添加扩展方法Iterable<T>?
:
void main() {
final Map<String, Iterable<int>> map = {};
for (final value in map['test'].emptyIfNull) {
// Do something with value
}
}
extension EmptyIfNullIterableExtension<T> on Iterable<T>? {
Iterable<T> get emptyIfNull => this ?? Iterable<T>.empty();
}
这是允许的,因为扩展方法是静态解析的,并且通过在可空类型上添加方法,我们实际上甚至可以在null
.
但这也意味着如果最终结果是dynamic
因为我们不能对类型为dynamic
. 原因是扩展方法实际上不是我们扩展的类的一部分,而是编译器自动插入调用的静态方法。这里的修复是添加一个类型转换。