【问题标题】:Dart - The argument type 'String' can't be assigned to the parameter type 'String'Dart - 参数类型“String”不能分配给参数类型“String”
【发布时间】:2020-04-15 21:14:10
【问题描述】:

我的代码很简单:

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

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

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

而 DartPad 在 message in printMessage(message) 中给了我这个错误:

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

看起来 Dart 是从一个 String 获得引用,而不是另一个,这怎么可能?

【问题讨论】:

    标签: dart


    【解决方案1】:

    既然您已经完成了typedef GenericCallback = void Function&lt;T&gt;(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);
    
    • 更新您的 typedef 以期待 String 参数
    typedef GenericCallback = void Function<T extends String>(T);
    
    GenericCallback callback = <T extends String>(T message) => printMessage(message);
    

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

    【讨论】:

    • 嗯,这很棘手,我来自 Java/C# 背景,我喜欢 Dart,但我想泛型需要更多的打磨。再次感谢本
    • 我在 Flutter 上找到了这个basic_types.dart:typedef ValueSetter&lt;T&gt; = void Function(T value);,它可以工作,但也很棘手,好像我做(String message) 它显示错误,但(message) 很好,应该是专业限制吧?
    • 那么,如果您需要为回调定义特定类型,那么使用泛型的想法是什么?
    猜你喜欢
    • 1970-01-01
    • 2023-04-05
    • 2021-10-02
    • 2021-10-20
    • 2021-10-06
    • 2021-09-06
    • 2021-09-16
    • 1970-01-01
    • 2021-08-20
    相关资源
    最近更新 更多