我有以下代码:
typedef Eater<T> = String Function(T value);
Eater<T> eaterFor<T>(T value) {
// Find an appropriate eater.
if (value is int) {
return ((int value) => 'Eating int $value.') as Eater<T>;
} else if (value is String) {
return ((String value) => 'Eating String $value.') as Eater<T>;
}
throw 'No eater found for $value.';
}
extension on Object? {
void eat() {
final eater = eaterFor(this);
print(eater(this)); // This fails.
}
}
void main() => 4.eat();
我希望可以打印出来Eating int 4.
,但是print
带有以下消息的行失败(在DartPad上,可能在VM上略有不同):
Closure 'eaterFor_closure': type '(int) => String' is not a subtype of type '(Object?) => String'
显然,类型的封闭(int) => String
不能与所谓的this
,它的类型的int
。我认为这应该可以以某种方式起作用,但是很明显,我关于Dart工作方式的思维模型与编译器不匹配。
我在这里想念什么?我们有一个闭包和一个与其输入变量类型匹配的值。我知道有很多强制转换和可能不是完全类型安全的部分,但是我们应该能够使用值调用闭包,不是吗?
到目前为止,这是我的尝试,但没有成功:
eater
到String Function(dynamic value)
this
到一个临时变量为什么会引发错误?我该如何称呼eater
with this
?
泛型和扩展名由编译器静态确定,而不由运行时确定。您的问题是以下内容:
extension on Object? {
void eat() {
final eater = eaterFor(this);
print(eater(this)); // This fails.
}
}
实际上被编译为以下内容:
extension on Object? {
void eat() {
final eater = eaterFor<Object?>(this);
print(eater(this)); // This fails.
}
}
Object?
如果类型T在运行时更精确,则编译器只能猜测类型T必须是事件。结果是您得到:
Eater<Object?> eaterFor(Object? value) {
// Find an appropriate eater.
if (value is int) {
return ((int value) => 'Eating int $value.') as Eater<Object?>;
} else if (value is String) {
return ((String value) => 'Eating String $value.') as Eater<Object?>;
}
throw 'No eater found for $value.';
}
这不是真的有效,因为:
String Function(Object? value);
可以接受更多类型的值作为输入int
。因此您的转换失败,因为((int value) => 'Eating int $value.')
不能转换为String Function(Object? value)
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句