【问题标题】:confusing about generics对泛型感到困惑
【发布时间】:2015-01-21 14:11:54
【问题描述】:

我尝试理解 Dart 泛型。当我编写自己的自定义泛型类时,我就了解泛型是如何工作的,比如

class Class1<T> {

    T func1(T para1, T para2) {
        return para1 = para2;
    }
}

main() {
    var mycl = new Class1<int>();
    print(mycl.func1(3, 5));
}

我知道,这是一个非常简单的例子,也许这没有意义,但无论如何,我大致知道如何使用泛型。

但是现在,我的问题是什么,看看这段代码

StreamSubscription<T> listen(Function void onData(T event), {Function onError, Function void onDone(), bool cancelOnError}) 

我从 HttpServer API 复制了这个并且是监听方法。我的问题是,Dart 是否支持泛型方法?我在网上搜索有关 Dart 泛型方法的信息,但找不到。

我真的很想了解,如何阅读 Dart API 文档,但有时很难理解。

【问题讨论】:

    标签: generics dart


    【解决方案1】:

    Dart 不支持泛型方法。

    您在这里看到的是一个属于泛型类的方法。 T 类型变量来自类class Stream&lt;T&gt;

    方法:

    StreamSubscription<T> listen(Function void onData(T event), {Function onError, Function void onDone(), bool cancelOnError})
    

    意味着在Stream&lt;int&gt; 上,listen 方法返回一个StreamSubscription&lt;int&gt;,它需要一个接受int 参数的onData 函数。

    例子:

    class Gift<T> {
      T _content;
      Gift(T content) : _content = _content;
      Gift<Gift<T>> wrap() => new Gift<Gift<T>>(this);
      T unwrap() => _content;
      T replace(T replacement(T current)) { 
        var old = _content; 
        _content = replacement(old);
        return old; 
      }
    }
    

    函数wrap 不是“通用的”。它根据当前对象的类型返回一个新类型。返回类型包含T,但它与调用该方法的Gift 的实例相同T

    函数replace 采用T -&gt; T 类型的参数。该方法不是“通用”的,它只是有一个类型,该类型取决于 Gift 实例中 T 的类型,它被称为一个。

    也就是说,这些方法不是通用的,因为每次调用它们时都可以使用新的 Type 参数对其进行参数化。相反,Gift 类是通用的,Gift 的每个实例都有一个类型参数的值。这种实例上的方法可以在其签名中使用该类型参数,但对于一个Gift 实例,类型始终相同。 Gift&lt;int&gt; 将有一个wrap 方法返回Gift&lt;Gift&lt;int&gt;&gt;,而replace 方法需要一个int -&gt; int 类型的参数。

    【讨论】:

    • 请给我看一些示例,我如何使用像 StreamSubscription 这样的泛型。谢谢
    【解决方案2】:

    Dart 并不需要它们。类型是可选的,您可以删除它们并使用“duck typing”。

    void main() {
      returnNthElement(int index, var something){
        return something[index];
      }
       print(returnNthElement(1, [1,2,3,4,5])); //2
       print(returnNthElement(1, "HELLO"));// E 
       print(returnNthElement(1, 100));//NoSuchMethodError: method not found: '[]'
    }
    

    但由于泛型类型在运行时持续存在,您可以像这样使用它们:

    void main() {
      foo(List l){
        if (l is List<int>) return "$l is list of ints";
        if (l is List<String>) return "$l is list of Strings";
      }
       var li = new List<int>();
       li.addAll([1,2,3,4,5]);
       var ls = new List<String>();
       ls.addAll(["HELLO", "DART"]);
       print(foo(li)); //[1, 2, 3, 4, 5] is list of ints
       print(foo(ls)); //[HELLO, DART] is list of Strings
    }
    

    【讨论】:

      猜你喜欢
      • 2020-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多