flutter 迁移到Dart null安全:迁移三元运算符null检查的最佳实践?一元方法是否过于非常规?

aij0ehis  于 6个月前  发布在  Flutter
关注(0)|答案(1)|浏览(59)

我正在将一个代码库迁移到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 ?

bjg7j2ky

bjg7j2ky1#

遗憾的是,三元运算符不支持使用空检查进行类型提升
这个前提是不正确的。三元运算子 * do * do type promotion。不过,只有同时为final和private的 local 变数或执行严修变数可以进行类型升级。另请参阅:

因此,您应该只引入一个局部变量(您似乎已经在if-elseNullFlatMap示例中实现了这一点):

MyType convert(OtherType value) {
  final field2 = value.field2;
  return MyType(
    field1: value.field1,
    field2: field2 != null ? MyWrapper(field2) : null,
  );
}

字符串

相关问题