如何在 List<T> 中创建泛型函数以在 Dart 中获取非可选类型 - Null Safety
How to make a generic functions in List<T> to get a Non-Optional type in Dart - Null Safety
我们正在将我们的 Flutter 应用程序迁移到 null safety 中,我遇到了一堆缺失的帮手以便轻松摆脱一个 optional 变成一个相同类型的 non-optional。
为了让您了解上下文,我想有一个
List<String?> optionalList = ['hi', 'hola', null];
并且类似于Swift中的compactMap()
,我想要一个函数,可以将任何映射转换为排除空项且仅包含return列表的映射非可选项目
例如:
final List<String> newNonOptionalList = optionalList.compactMap((item) => item.toUpperCase());
// newNonOptionalList = ['HI', 'HOLA']
我正在尝试为这些类型的案例提供帮助,包括我发现对 Dart.
有价值的许多其他案例
有没有人知道为什么它不起作用,这是我迄今为止尝试过的一些方法:
extension ListNullSafetyExtension<T> on List<T?>? {
Iterable<R> compactMap<R>(R Function(T element) convert) sync* {
for (var element in this.removeNulls()) {
if (element != null) yield convert(element);
}
}
List<T> removeNulls() {
if (this == null) return [];
this!.removeWhere((value) => (value == null));
return List.from(this!).whereType<T>().toList();
}
}
即使这确实删除了空值并执行了映射,它始终 return 列表中的可选类型相同,这意味着它不会解包并且 removeNulls()
return 是 List<dynamic>
而不是 List<the_type_I_used>
非常感谢您帮助我理解为什么这 2 个函数从不改变它们的类型,因为我只能找到该主题的非常基本的泛型帖子。
改变这个:
final List<String> newNonOptionalList = optionalList.compactMap((item) => item.toUpperCase());
至此
final List<String> newNonOptionalList = optionalList.compactMap((item) => item.toUpperCase()).toList();
您可以轻松地将 List<T?>
折叠为 List<T>
,并使用 Iterable.whereType<T>()
:
过滤掉 null
个元素
List<String?> optionalList = ['hi', 'hola', null];
List<String> newNonOptionalList = optionalList.whereType<String>().toList();
如果你真的想要自己的扩展方法(即使它添加的不多):
extension IterableNullSafetyExtension<T> on Iterable<T?>? {
Iterable<T> removeNulls() => this?.whereType<T>() ?? [];
}
此外,您尝试实施的一个错误是 ListNullSafetyExtension<T>
已经是通用的并且在 T
上参数化了。当您稍后尝试添加扩展方法时:
List<T> removeNulls<T>() {
末尾的额外 <T>
使用独立于 T
的 T
再次使 removeNulls
通用 来自 ListNullSafetyExtension
。不要那样做。
我们正在将我们的 Flutter 应用程序迁移到 null safety 中,我遇到了一堆缺失的帮手以便轻松摆脱一个 optional 变成一个相同类型的 non-optional。
为了让您了解上下文,我想有一个
List<String?> optionalList = ['hi', 'hola', null];
并且类似于Swift中的compactMap()
,我想要一个函数,可以将任何映射转换为排除空项且仅包含return列表的映射非可选项目
例如:
final List<String> newNonOptionalList = optionalList.compactMap((item) => item.toUpperCase());
// newNonOptionalList = ['HI', 'HOLA']
我正在尝试为这些类型的案例提供帮助,包括我发现对 Dart.
有价值的许多其他案例有没有人知道为什么它不起作用,这是我迄今为止尝试过的一些方法:
extension ListNullSafetyExtension<T> on List<T?>? {
Iterable<R> compactMap<R>(R Function(T element) convert) sync* {
for (var element in this.removeNulls()) {
if (element != null) yield convert(element);
}
}
List<T> removeNulls() {
if (this == null) return [];
this!.removeWhere((value) => (value == null));
return List.from(this!).whereType<T>().toList();
}
}
即使这确实删除了空值并执行了映射,它始终 return 列表中的可选类型相同,这意味着它不会解包并且 removeNulls()
return 是 List<dynamic>
而不是 List<the_type_I_used>
非常感谢您帮助我理解为什么这 2 个函数从不改变它们的类型,因为我只能找到该主题的非常基本的泛型帖子。
改变这个:
final List<String> newNonOptionalList = optionalList.compactMap((item) => item.toUpperCase());
至此
final List<String> newNonOptionalList = optionalList.compactMap((item) => item.toUpperCase()).toList();
您可以轻松地将 List<T?>
折叠为 List<T>
,并使用 Iterable.whereType<T>()
:
null
个元素
List<String?> optionalList = ['hi', 'hola', null];
List<String> newNonOptionalList = optionalList.whereType<String>().toList();
如果你真的想要自己的扩展方法(即使它添加的不多):
extension IterableNullSafetyExtension<T> on Iterable<T?>? {
Iterable<T> removeNulls() => this?.whereType<T>() ?? [];
}
此外,您尝试实施的一个错误是 ListNullSafetyExtension<T>
已经是通用的并且在 T
上参数化了。当您稍后尝试添加扩展方法时:
List<T> removeNulls<T>() {
末尾的额外 <T>
使用独立于 T
的 T
再次使 removeNulls
通用 来自 ListNullSafetyExtension
。不要那样做。