Dart:如何检查有时可为空的泛型类型的类型?

问题描述 投票:0回答:1

给定以下 dart 3 代码片段,是否可以匹配 switch 子句中可空的

A
,并找出
A
是哪种可空的? (
String?
int?
等) 类型检查器错误地假设
A
永远不能为空,最终我得到了一个我似乎无法匹配的情况。

void main() {
  String? x = test(null);
  String y = test("hi");
}

A test<A extends Object?>(A a) {
  switch((A,a.runtimeType)){
    case (String,Null) :
      print("found miscasted nullable string");
    case (String,_) : 
      print("found non-null string: $a");
    // This case should match, but something is weird.
    case (String?,_) :
      print("found nullable string");
    case (var x,Null):
      print("found something null: $x $a");
      if(x is String?)
        print("$x is String?");
      else
        print("$x is not String?");
    case (_,_):
      print("failed matching completely" ); 
  };
  return a;
}

输出变成

found something null: String? null
    String? is not String?
found non-null string: hi

而且我似乎找不到一种方法来将输入类型与

String?
相匹配。

我需要这个在 Flutter 中工作,所以 dart:mirror 不能成为解决方案。

flutter dart generics nullable typechecking
1个回答
0
投票

注意分析仪发出的消息:

空检查模式将无效,因为匹配的类型不可为空。

模式中的

String?
不检查
A == String?
,它被视为 空检查模式,这是
String
上的一种单独的模式。

这也是分析器抱怨

case (String?, _)
case (String, _)
冗余的原因:

此案例包含在之前的案例中。

另请注意,您的检查

if (x is String?)
也不起作用,因为
x
A
匹配,并且
A is B
检查
A
是否是 B
实例
String
不是
String?
的实例;
String
(和
String?
)是
Type
类的实例。

我不确定你是否可以用模式做你想做的事,但你可以这样做:

void main() {
  String? x = test(null);
  String y = test("hi");
}

// See <https://stackoverflow.com/q/67446069/>.
bool isNullable<T>() => <T?>[] is List<T>;

// See <https://github.com/dart-lang/language/issues/1312#issuecomment-727284104>.
bool isSubtype<S, T>() => <S>[] is List<T>;

A test<A extends Object?>(A a) {
  if (A == String) {
    if (a == null) {
      // Note that this isn't possible.
      print("found miscasted nullable string");
    } else {
      print("found non-null string: $a");
    }
  } else if (isNullable<A>()) {
    print("found nullable string");
  } else if (a == null) {
    print("found something null: $A $a");

    if (isSubtype<A, String?>()) {
      print("$A is String?");
    } else {
      print("$A is not String?");
    }
  } else {
    print("failed matching completely");
  }
  return a;
}
© www.soinside.com 2019 - 2024. All rights reserved.