给出下面的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 :镜子不能解决问题.

Edit:多亏了@jamesdlin的回答,我现在的代码中有了以下函数:

Type typeOf<A>() => A;
bool isSomeKindOf<T,S>() => S == typeOf<T>() || S ==  typeOf<T?>();

.这意味着我现在可以做像这样的事情

bool isIntOrNullableInt<A>(A a) => isSomeKindOf<int,A>();
print(isIntOrNullableInt(3)); // true
print(isIntOrNullableInt(null as Int?)); // true
print(isIntOrNullableInt("3")); // false

这意味着我现在可以做一些事情,比如

A getOrDefault<A>(String token, A defaultVal) =>
    (
    isSomeKindOf<int,A>() ? source.getInt(token) ?? defaultVal :
    isSomeKindOf<String,A>() ? source.getString(token) ?? defaultVal :
    defaultVal
    ) as A; 

which works whether A is a Foo or a Foo?, which was my secret agenda all along.
This lets me finally have the following working:

String prop1 = getOrDefault("prop1", "property missing");
int? prop2 = getOrDefault("prop2", null);

推荐答案

注意来自分析器的消息(增加了强调):

null-check pattern将不起作用,因为匹配的类型不能为空.

你的模式中的String?不是判断A == String?,它被视为null-check pattern,这是一种单独的模式,该模式应用于String.

这也是为什么分析仪抱怨case (String?, _)case (String, _)是多余的:

此案已包括在之前的案件中.

还请注意,您的支票if (x is String?)也不会起作用,因为xAA is B checks if A is an instance of B匹配.StringString?的实例;String(和String?)是Type类的实例.

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

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

Type identityType<T>() => T;

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

    // `A == String?` is not legal syntax.
  } else if (A == identityType<String?>()) {
    print("found nullable string");
  } else if (a == null) {
    print("found something null: $A $a");

    if (A == identityType<String?>()) {
      // This is not possible since it would have been caught earlier.
      print("$A is String?");
    } else {
      print("$A is not String?");
    }
  } else {
    print("failed matching completely");
  }
  return a;
}

Flutter相关问答推荐

Flutter 导致底部溢出

如果文档确实存在,则FiRestore将";False";返回到";if-Document-Existes";...还是我说错了?

Flutter -如何停止块监听程序在后台堆栈中运行

Flutter -如何将导航轨道标签靠左对齐?

如何将Visual Studio代码中Flutter 应用的包名从com.example.XXX更改为Play Store中受限制的包名称

BottomNavigationBar-我应该使用Container和Align吗?

Flutter:无法构建iOS应用程序-找不到PigeonParser.h文件

尽管我的 url 链接正确,但 ArgumentError(无效参数:URI 文件中未指定主机:///)错误

构建上下文不能跨异步间隙使用

Flutter:注册 UI 出现 UI 问题(将注册框提升到顶部并向电话号码 pin 码添加一个框)

Flutter:如何在现有布局之上显示圆角布局?

Elevated 和 Outlined 按钮之间的动画

面对Flutter 中的行和列问题

应用程序包含嵌入式私钥或密钥库文件

如何从 Flutter Slider Widget 中移除发光效果?

Flutter RawMaterialButton 常量相对大小

Flutter - 异步文件读取异常处理

如何在Flutter 中水平滚动堆叠定位的小部件?

在列表视图Flutter 中 Select 下一个单选按钮时单选按钮更改

如何使用我拥有的 .jks 文件签署我的应用程序