Dart-无法将参数类型'String'分配给参数类型'String' [英] Dart - The argument type 'String' can't be assigned to the parameter type 'String'

查看:786
本文介绍了Dart-无法将参数类型'String'分配给参数类型'String'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码非常简单:

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

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

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

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

And DartPad gives me this error at the word message in printMessage(message):

错误:无法将参数类型'String/* 1 */'分配给参数类型'String/* 2 */'.
 -'String/* 1 */'来自'unknown'.
 -'String/* 2 */'来自'dart:core'.

Error: The argument type 'String/*1*/' can't be assigned to the parameter type 'String/*2*/'.
 - 'String/*1*/' is from 'unknown'.
 - 'String/*2*/' is from 'dart:core'.

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

It looks like Dart is getting the reference from one String and not the other, how's this even possible?

推荐答案

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

Since you've done typedef GenericCallback = void Function<T>(T) you need to provide a generic method which matches the signature as a callback. The tricky part here is, you are doing that but not in the way you think.

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

In this line it looks like you're trying to specify the type for the closure you've created:

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

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

However, Dart's rules for naming generic type parameters are strange in that you can use the names of existing types as the name of the type parameter. In other words, the following lines are all functionally identical and will provide a similar error:

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

这些通用闭包都是完全有效的,甚至内置类型(如 int String )也将被视为闭包范围内类型参数的名称.

These generic closures are all completely valid and even built-in types like int and String will be treated as the names for type parameters in the scope of the closure.

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

In order to fix your error, you'll want to change the type parameter String to have a different name that doesn't collide with a core type, and do one of the following:

  • 更新您对 printMessage 的调用以将 message 转换为 String ,尽管如果 T 不是调用闭包时,其类型为 String .
  • Update your invocation of printMessage to cast message to a String, although this will fail if T isn't of type String when the closure is called.
GenericCallback callback = <T>(T message) => printMessage(message as String);

  • 更新您的typedef以期望使用 String 参数
  • typedef GenericCallback = void Function<T extends String>(T);
    
    GenericCallback callback = <T extends String>(T message) => printMessage(message);
    

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

    This is an easy mistake to make if you've come from a language which allows for template/generic specialization like C++. Keep in mind that, at least currently, you can't specialize a generic method or object and the generic type isn't assigned until the method is actually called or object is created.

    这篇关于Dart-无法将参数类型'String'分配给参数类型'String'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆