我的代码非常简单:
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
而不是另一个获取引用,这怎么可能?
答案 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);
这些通用闭包都是完全有效的,甚至int
和String
之类的内置类型也将被视为闭包范围内类型参数的名称。
为了解决错误,您需要将类型参数String
更改为具有不与核心类型冲突的其他名称,然后执行以下操作之一:
printMessage
的调用以将message
转换为String
,尽管如果T
在关闭时String
不是GenericCallback callback = <T>(T message) => printMessage(message as String);
类型,则会失败被称为。String
typedef GenericCallback = void Function<T extends String>(T);
GenericCallback callback = <T extends String>(T message) => printMessage(message);
参数{{1}}
如果您来自支持模板/通用专业化(如C ++)的语言,这是一个容易犯的错误。请记住,至少在当前,您不能专门化泛型方法或对象,并且在实际调用该方法或创建对象之前,不会分配泛型类型。