我对 Dart 比较陌生,并且正在尝试对代数数据类型进行建模(例如 Swift 的具有关联值的枚举)。
但是,当我尝试检查值的运行时类型时,我看到了一些我不太了解的行为。考虑以下代码:
abstract class Fetchable<T> {
factory Fetchable.success(T object) = FetchableSuccess;
factory Fetchable.error(Error error) = FetchableError;
}
class FetchableSuccess<T> implements Fetchable<T> {
final T object;
const FetchableSuccess(this.object);
}
class FetchableError<T> implements Fetchable<T> {
final Error error;
const FetchableError(this.error);
}
void main() {
// ------------- CASE 1 -------------
final s = Fetchable.success("hi there");
print(s.runtimeType); // FetchableSuccess<dynamic>
print(s is FetchableSuccess); // true
print(s is FetchableSuccess<String>); // false
print(s is FetchableSuccess<dynamic>); // true
if (s is FetchableSuccess) {
print(s.object); // compile error
}
if (s is FetchableSuccess<dynamic>) {
print(s.object); // compile error
}
// ------------- CASE 2 -------------
final e = Fetchable.error(StateError("uh oh"));
print(e is FetchableError); // true
if (e is FetchableError) {
print(e.error); // Works OK
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我创建了两个案例……我似乎无法object从success案例中提取变量。该is关键字告诉我,这是一个FetchableSuccess<dynamic>(这似乎很奇怪......我以为飞镖不会删除类型?我本来期望它是一个FetchableSuccess<String>)
尽管如此,如果我转换FetchableSuccess<dynamic>为编译器仍然告诉我它不知道子类中的object变量FetchableSuccess。
相比之下,to FetchableError(它没有显式使用 type 的值T)...is工作正常并且编译器能够访问该error变量。
我错过了什么?任何指导将不胜感激。
我们这里有几个问题:首先,您需要添加<T>到两个工厂构造函数的右侧。
如果你这样做, 的运行时类型s将是ReflectableSucces<String>它应该的样子,并且你将从true中的以下 3 行得到main。
然后您正在测试s is FetchableSuccesswhichmeans s is FetchableSuccess<dynamic>,并且这不是静态已知类型的子类型Fetchable<String>,因此您不会得到提升(因此静态类型中没有object吸气剂,因此会出现错误)。显式测试s is FetchableSucces<dynamic>当然也受到同样的处理。
所以剩下的问题是,为什么那些缺失的 s 不会出现错误<T>?我现在正在寻找问题,这可能是一个已知的错误。
更新: https: //github.com/dart-lang/sdk/issues/34714解决了公共前端中没有进行推理的事实,尽管应该这样做。因此,我们使用来自分析器的推理进行分析,然后我们在运行时获得不使用推理的语义(因此默认为<dynamic>),这就是为什么我们会遇到这种不幸的冲突,其中实际类型参数是错误的运行时,并且没有编译时错误。当上述问题落地时应该得到解决。
| 归档时间: |
|
| 查看次数: |
3219 次 |
| 最近记录: |