【发布时间】:2013-04-21 06:05:37
【问题描述】:
我想在 dart 中创建一个更专业的列表。我不能直接扩展List。我有哪些选择?
【问题讨论】:
标签: dart
我想在 dart 中创建一个更专业的列表。我不能直接扩展List。我有哪些选择?
【问题讨论】:
标签: dart
要让一个类实现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
}
DelegatingList 委托给另一个List:import 'package:quiver/collection.dart';
class MyCustomList<E> extends DelegatingList<E> {
final List<E> _l = [];
List<E> get delegate => _l;
// your custom methods
}
DelegatingList 委托给另一个List: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 允许扩展另一个对象)。
【讨论】:
Base 告诉 Minin can apply only for classes | undefined class Base 下的 IDE 出现错误!
List 转换为MyCustomList,我可以开发类似.MyCustomList 左右的东西!
dart:collection 中有一个 ListBase 类。如果你扩展这个类,你只需要实现:
get lengthset 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);
}
【讨论】:
add 和 addAll。这些是大量使用的方法,当它们不通过length 和[] 时效率更高。见dartbug.com/12652。
扩展类的新方法是introduced with Dart 2.6。
您现在可以像这样创建List 的extension:
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.
【讨论】:
这个问题的答案已经过时了,我正在为我自己的项目做这个,所以我想我会通过发布一个不涉及任何覆盖或覆盖的非常干净的答案来帮助一些人事情的执行。
quiver 包有一个名为 DelegatingList 的可扩展列表类,它使扩展列表变得很简单。
class FruitList extends DelegatingList<Fruit> {
final List<Fruit> _fruits = [];
List<Fruit> get delegate => _fruits;
// custom methods
}
希望这可以帮助像我一样遇到这个问题的人!
【讨论】:
根据上面的答案,您可以像这样创建一个不可变列表:
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];
}
【讨论】:
//list is your given List and iterable is any object in dart that can be iterated
list.addAll(Iterable)
【讨论】: