微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决在飞镖,类型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.';
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。