给出下面的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);