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
相关产品推荐
相关产品推荐

