在飞镖,类型INT的函数=>字符串不能与INT称为

问题描述

我有以下代码:

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。 我想,这应该以某种方式工作,但显然,我的飞镖是如何工作的编译器不匹配的心智模式。

我在这里错过了什么?我们有一个封闭和匹配其输入变量的类型的值。 我知道有很多铸件,也许 - 不完全类型安全的部分,但我们应该能够调用盖子与价值,不是吗?

下面是我的尝试,到目前为止,没有工作:

  • 铸造eaterString Function(dynamic value)
  • 保存this到临时变量

正是为什么错误时,抛出? 以及如何使用 eater 调用 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.
  }
}

如果类型在运行时可以更精确,编译器只能猜测类型 T 必须是 Object? 事件。这有你得到的结果:

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)

,

你不应该另外转换参数

Eater<T> eaterFor<T>(T value) {
  // Find an appropriate eater.
  if (value is int) {
    return ((T value) => 'Eating int $value.');
  } else if (value is String) {
    return ((T value) => 'Eating String $value.');
  }
  throw 'No eater found for $value.';
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...