【问题标题】:How do I extend a List in Dart?如何在 Dart 中扩展列表?
【发布时间】:2013-04-21 06:05:37
【问题描述】:

我想在 dart 中创建一个更专业的列表。我不能直接扩展List。我有哪些选择?

【问题讨论】:

    标签: dart


    【解决方案1】:

    要让一个类实现List,有几种方法:

    import 'dart:collection';
    
    class MyCustomList<E> extends ListBase<E> {
      final List<E> l = [];
      MyCustomList();
    
      void set length(int newLength) { l.length = newLength; }
      int get length => l.length;
      E operator [](int index) => l[index];
      void operator []=(int index, E value) { l[index] = value; }
    
      // your custom methods
    }
    
    import 'dart:collection';
    
    class MyCustomList<E> extends Base with ListMixin<E> {
      final List<E> l = [];
      MyCustomList();
    
      void set length(int newLength) { l.length = newLength; }
      int get length => l.length;
      E operator [](int index) => l[index];
      void operator []=(int index, E value) { l[index] = value; }
    
      // your custom methods
    }
    
    import 'package:quiver/collection.dart';
    
    class MyCustomList<E> extends DelegatingList<E> {
      final List<E> _l = [];
    
      List<E> get delegate => _l;
    
      // your custom methods
    }
    
    import 'package:collection/wrappers.dart';
    
    class MyCustomList<E> extends DelegatingList<E> {
      final List<E> _l;
    
      MyCustomList() : this._(<E>[]);
      MyCustomList._(l) :
        _l = l,
        super(l);
    
      // your custom methods
    }
    

    根据您的代码,每个选项都有其优势。如果您包装/委托现有列表,则应使用最后一个选项。否则,根据您的类型层次结构使用前两个选项之一(mixin 允许扩展另一个对象)。

    【讨论】:

    • 您也可以使用 package:collection/wrappers.dart 中的 DelegatingList,其方式与 quiver 中的类似。
    • 我正在尝试第二个选项,但在 Base 告诉 Minin can apply only for classes | undefined class Base 下的 IDE 出现错误!
    • 使用第一种方法,如何用这种方法定义列表列表,我无法定义`MyCustomList [MyCustomList]' :(
    • 另外一点,有没有办法将我的List 转换为MyCustomList,我可以开发类似.MyCustomList 左右的东西!
    • 如果我基本上只需要一个“typedef”,那么最好的方法是什么,例如定义类 Grid 以摆脱 List> 定义。是否可以跳过重新定义 getter 和 setter 并委托给 super?
    【解决方案2】:

    dart:collection 中有一个 ListBase 类。如果你扩展这个类,你只需要实现:

    • get length
    • set length
    • []=
    • []

    这是一个例子:

    import 'dart:collection';
    
    class FancyList<E> extends ListBase<E> {
      List innerList = new List();
    
      int get length => innerList.length;
    
      void set length(int length) {
        innerList.length = length;
      }
    
      void operator[]=(int index, E value) {
        innerList[index] = value;
      }
    
      E operator [](int index) => innerList[index];
    
      // Though not strictly necessary, for performance reasons
      // you should implement add and addAll.
    
      void add(E value) => innerList.add(value);
    
      void addAll(Iterable<E> all) => innerList.addAll(all);
    }
    
    void main() {
      var list = new FancyList();
    
      list.addAll([1,2,3]);
    
      print(list.length);
    }
    

    【讨论】:

    • 这个问题专门询问了选项,你能澄清一下你还能做什么吗?
    • @amouravski 我很想知道 :)
    • 我猜另外两个选项是实现 List 接口,或者使用 List 作为 mixin。
    • 为了性能,通常还应该至少覆盖(和委托)addaddAll。这些是大量使用的方法,当它们不通过length[] 时效率更高。见dartbug.com/12652
    • 只是为了好奇。 表示任何类型的对象?如果我想实现一个只接受 的 List 女巫,我应该用所有 替换 吗?
    【解决方案3】:

    扩展类的新方法是introduced with Dart 2.6
    您现在可以像这样创建Listextension

    extension MyCustomList<T> on List<T> {
      // Any methods you want can be added here.
    }
    

    您添加can be used implicitly 的方法,即当您导入extension 时,您可以在任何List 上使用它们。
    这是example from the feature specification

    extension MyFancyList<T> on List<T> {
      int get doubleLength => this.length * 2;
      List<T> operator-() => this.reversed.toList();
      List<List<T>> split(int at) => 
          <List<T>>[this.sublist(0, at), this.sublist(at)];
      List<T> mapToList<R>(R Function(T) convert) => this.map(convert).toList();
    }
    

    您可以在任何List 上使用这些新成员,例如像这样:

    const list = <String>['some', 'elements'];
    
    list.doubleLength; // Evaluates to 4.
    

    【讨论】:

      【解决方案4】:

      这个问题的答案已经过时了,我正在为我自己的项目做这个,所以我想我会通过发布一个不涉及任何覆盖或覆盖的非常干净的答案来帮助一些人事情的执行。

      quiver 包有一个名为 DelegatingList 的可扩展列表类,它使扩展列表变得很简单。

      class FruitList extends DelegatingList<Fruit> {
          final List<Fruit> _fruits = [];
      
          List<Fruit> get delegate => _fruits;
      
          // custom methods
      }
      

      希望这可以帮助像我一样遇到这个问题的人!

      【讨论】:

        【解决方案5】:

        根据上面的答案,您可以像这样创建一个不可变列表:

        class ImmutableList<E> extends ListBase<E> {
          late final List<E> innerList;
        
          ImmutableList(Iterable<E> items) {
            innerList = List<E>.unmodifiable(items);
          }
        
          @override
          int get length => innerList.length;
        
          @override
          set length(int length) {
            innerList.length = length;
          }
        
          @override
          void operator []=(int index, E value) {
            innerList[index] = value;
          }
        
          @override
          E operator [](int index) => innerList[index];
        }
        

        【讨论】:

          【解决方案6】:
              //list is your given List and iterable is any object in dart that can be iterated
              list.addAll(Iterable)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-02-22
            • 2020-02-06
            • 2013-12-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多