Dart-无法将参数类型'String'分配给参数类型'String'

时间:2019-12-25 02:08:47

标签: dart

我的代码非常简单:

typedef GenericCallback = void Function<T>(T);

void main() {
  GenericCallback callback = <String>(String message) => printMessage(message);
}

void printMessage([String errorMessageReason]) {
  print(errorMessageReason ?? '');
}

DartPad在message中的单词printMessage(message)上给了我这个错误:

  

错误:参数类型'String / * 1 * /'无法分配给参数类型'String / * 2 * /'。
  -“字符串/ * 1 * /”来自“未知”。
  -'String / * 2 * /'来自'dart:core'。

Dart似乎从一个String而不是另一个获取引用,这怎么可能?

1 个答案:

答案 0 :(得分:3)

完成typedef GenericCallback = void Function<T>(T)后,您需要提供一个与签名匹配的通用方法作为回调。这里最棘手的部分是,您正在这样做,但并非以您的思维方式进行。

在此行中,您似乎正在尝试为创建的闭包指定类型:

GenericCallback callback = <String>(String message) => printMessage(message);

但是,Dart的泛型类型参数命名规则很奇怪,因为您可以使用现有类型的名称​​作为类型参数的名称。换句话说,以下几行在功能上完全相同,并且会提供类似的错误:

GenericCallback callback = <String>(String message) => printMessage(message);
GenericCallback callback = <T>(T message) => printMessage(message);
GenericCallback callback = <int>(int message) => printMessage(message);

这些通用闭包都是完全有效的,甚至intString之类的内置类型也将被视为闭包范围内类型参数的名称。

为了解决错误,您需要将类型参数String更改为具有不与核心类型冲突的其他名称,然后执行以下操作之一:

  • 更新对printMessage的调用以将message转换为String,尽管如果T在关闭时String不是GenericCallback callback = <T>(T message) => printMessage(message as String); 类型,则会失败被称为。
String
  • 更新您的typedef以期望使用typedef GenericCallback = void Function<T extends String>(T); GenericCallback callback = <T extends String>(T message) => printMessage(message); 参数
{{1}}

如果您来自支持模板/通用专业化(如C ++)的语言,这是一个容易犯的错误。请记住,至少在当前,您不能专门化泛型方法或对象,并且在实际调用该方法或创建对象之前,不会分配泛型类型。