32

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

4

6 回答 6

36

让一个类实现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 允许扩展另一个对象)。

于 2013-08-29T10:09:41.403 回答
18

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);
}
于 2013-04-27T00:34:30.363 回答
14

Dart 2.6 引入了一种扩展类的新方法。
您现在可以创建一个这样extension的:List

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

您添加的方法可以隐式使用,即您可以在导入List时使用它们。 这是功能规范中的一个示例extension

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();
}

您可以在 any 上使用这些新成员List,例如:

const list = <String>['some', 'elements'];

list.doubleLength; // Evaluates to 4.
于 2019-10-08T22:28:14.577 回答
5

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

quiver包有一个名为DelegatingList的可扩展列表类,它使扩展列表变得微不足道。

class FruitList extends DelegatingList<Fruit> {
    final List<Fruit> _fruits = [];

    List<Fruit> get delegate => _fruits;

    // custom methods
}

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

于 2020-03-03T10:26:14.583 回答
0

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

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];
}
于 2021-06-23T08:31:38.997 回答
-2
    //list is your given List and iterable is any object in dart that can be iterated
    list.addAll(Iterable)
于 2020-03-29T10:08:28.523 回答