如何解决Dart:如何在运行时确定可为空的泛型类型?
我需要在运行时确定 泛型类型 是 String
、bool
、int
、double
还是其他类。我没有找到针对可为空类型的方法:
class Foo<T> {
void foo() {
if (T == int) {
print("'T' is an int");
} else {
print("'T' is not an int");
}
}
}
void main() {
final foo = Foo<int>();
final bar = Foo<int?>();
foo.foo();
bar.foo();
}
控制台输出:
// 'T' is an int
// 'T' is not an int
是否有任何我不知道的语法来检查可空类型?,我已经尝试过 int?
但它无法编译。
解决方法
这里有一个更具体的例子,基于 How do I check whether a generic type is nullable in Dart NNBD? 的方法。
注意 when transpiling to JavaScript,all numbers are IEEE-754 double-precision floating-point values,所以要区分 Dart double
/double?
和 int
/int?
,我们必须先检查一个浮点字面量不能是 int
。
void foo<T>() {
if (1.5 is T) {
if (null is T) {
print('double?');
} else {
print('double');
}
} else if (1 is T) {
if (null is T) {
print('int?');
} else {
print('int');
}
} else {
print('something else');
}
}
void main() {
foo<int?>(); // Prints: int?
foo<int>(); // Prints: int
foo<double?>(); // Prints: double?
foo<double>(); // Prints: double
foo<bool>(); // Prints: something else
}
请注意,上述方法不适用于 void
或 Null
。 Null
可以通过检查 T == Null
来处理,但 T == void
不是有效的语法(类似于 T == int?
)。您可以通过将它们作为进行比较的泛型函数的类型参数来解决这个问题,因此另一种方法是:
/// Returns true if T1 and T2 are identical types.
///
/// This will be false if one type is a derived type of the other.
bool typesEqual<T1,T2>() => T1 == T2;
void foo<T>() {
if (typesEqual<T,void>()) {
print('void');
} else if (typesEqual<T,Null>()) {
print('Null');
} else if (typesEqual<T,int>()) {
print('int');
} else if (typesEqual<T,int?>()) {
print('int?');
} else if (typesEqual<T,double>()) {
print('double');
} else if (typesEqual<T,double?>()) {
print('double?');
} else {
print('something else');
}
}
void main() {
foo<int?>(); // Prints: int?
foo<int>(); // Prints: int
foo<double?>(); // Prints: double?
foo<double>(); // Prints: double
foo<void>(); // Prints: void
foo<Null>(); // Prints: Null
foo<bool>(); // Prints: something else
}
,
我建议避免将 Type
对象用于任何严肃的事情(打印或 dart:mirrors
除外)。
您可以创建函数来检查作为类型参数提供的两种类型是否等效。以下是一些示例:
/// Whether two types are equivalent.
///
/// The types are equivalent if they are mutual subtypes.
bool equivalentTypes<S,T>() {
return _Helper<S Function(S)>() is _Helper<T Function(T)>;
}
class _Helper<T> {}
// Or alternatively:
bool equivalentTypes2<S,T>() {
S func(S value) => value;
return func is T Function(T);
}
/// Whether two types are the same type.
///
/// Uses the same definition as the language specification for when
/// two types are the same.
/// Currently the same as mutual subtyping.
bool sameTypes<S,T>() {
void func<X extends S>() {}
// Spec says this is only true if S and T are "the same type".
return func is void Function<X extends T>();
}
void main() {
print(equivalentTypes<int,int>());
print(equivalentTypes<int?,int?>());
print(equivalentTypes<int?,int>());
print(equivalentTypes2<int,int>());
print(equivalentTypes2<int?,int?>());
print(equivalentTypes2<int?,int>());
print(sameTypes<int,int>());
print(sameTypes<int?,int?>());
print(sameTypes<int?,int>());
}
该语言只有一个用于将类型与任何内容进行比较的运算符,即 is
运算符,它将对象与类型进行比较。这就是为什么这里的所有函数都会创建一个依赖于 S
的已知类型的对象,并根据依赖于 T
的类型来检查它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。