You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

Dart 3中如何在switch语句匹配可空泛型类型?

问题背景

在Dart 3中尝试在switch语句里匹配可空泛型类型(如String?、int?)时,类型检查器会错误判定泛型参数A永远不可空,导致无法命中对应的case分支。且由于需要适配Flutter环境,不能使用dart:mirrors方案。

原代码示例

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");
    // 预期匹配但无法命中的分支
    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

解决方案

通过实现typeOf辅助函数来完成可空与非可空类型的匹配:

辅助函数实现

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

扩展实现getOrDefault函数

基于上述辅助函数,可以实现支持可空与非可空类型的取值函数:

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

最终使用示例

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

内容的提问来源于stack exchange,提问作者stobix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 14:20:07