我正在将一个代码库迁移到null安全,它包括很多这样的代码:
MyType convert(OtherType value) {
return MyType(
field1: value.field1,
field2: value.field2 != null ? MyWrapper(value.field2) : null,
);
}
字符串
不幸的是,三元运算符不支持带null检查的类型提升,这意味着我必须添加!
来Assert它不是null,以便使它在null安全下编译:
MyType convert(OtherType value) {
return MyType(
field1: value.field1,
field2: value.field2 != null ? MyWrapper(value.field2!) : null,
);
}
型
这使得代码有点不安全;人们可以很容易地想象一个场景,其中空检查被修改,或者一些代码被复制和粘贴到!
导致崩溃的情况。
所以我的问题是,是否有一个特定的最佳实践来更安全地处理这种情况?重写代码来直接利用流分析和类型提升是笨拙的:
MyType convert(OtherType value) {
final rawField2 = value.field2;
final MyWrapper? field2;
if (rawField2 != null) {
field2 = MyWrapper(rawField2);
} else {
field2 = null;
}
return MyType(
field1: value.field1,
field2: field2,
);
}
型
作为一个在函数式编程方面思考很多的人,我的直觉是将可空类型视为monad,并相应地定义map
:
extension NullMap<T> on T? {
U? map<U>(U Function(T) operation) {
final value = this;
if (value == null) {
return null;
} else {
return operation(value);
}
}
}
型
那么这种情况可以这样处理:
MyType convert(OtherType value) {
return MyType(
field1: value.field1,
field2: value.field2.map((f) => MyWrapper(f)),
);
}
型
这似乎是一个很好的方法来保持安全性和简洁性。然而,我在网上搜索了很长时间,我找不到其他人在Dart中使用这种方法。有几个例子定义了一个Optional
monad,似乎早于null safety,但是我找不到任何Dart开发人员直接在可空类型上定义map
的例子。这里有什么我遗漏的主要问题吗?有没有其他的方法,这是既符合人体工程学和更传统的 dart ?
1条答案
按热度按时间bjg7j2ky1#
遗憾的是,三元运算符不支持使用空检查进行类型提升
这个前提是不正确的。三元运算子 * do * do type promotion。不过,只有同时为
final
和private的 local 变数或执行严修变数可以进行类型升级。另请参阅:因此,您应该只引入一个局部变量(您似乎已经在
if
-else
和NullFlatMap
示例中实现了这一点):字符串