Как мне расширить список в дартс?
Я хочу создать более специализированный список в дартс. Я не могу напрямую расширить список. Какие у меня варианты?
6 ответов
В 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);
}
Чтобы сделать класс реализующим List, есть несколько способов:
- Расширение ListBase и реализация
length
,operator[]
,operator[]=
а такжеlength=
:
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
}
- Mixin ListMixin и реализации
length
,operator[]
,operator[]=
а такжеlength=
:
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
}
- Делегирование другому
List
сDelegatingList
из пакета колчан:
import 'package:quiver/collection.dart';
class MyCustomList<E> extends DelegatingList<E> {
final List<E> _l = [];
List<E> get delegate => _l;
// your custom methods
}
- Делегирование другому
List
сDelegatingList
из коллекции пакета:
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
}
В зависимости от вашего кода каждый из этих вариантов имеет свои преимущества. Если вы переносите / делегируете существующий список, вы должны использовать последний вариант. В противном случае используйте один из двух первых вариантов в зависимости от вашей иерархии типов (миксин, позволяющий расширить другой объект).
Новый способ расширения классов был представлен в 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();
}
Вы можете использовать этих новых участников на любом List
, например, вот так:
const list = <String>['some', 'elements'];
list.doubleLength; // Evaluates to 4.
Ответы на этот вопрос довольно устарели, и я сейчас делаю это для своего собственного проекта, поэтому я подумал, что помогу некоторым людям, опубликовав действительно чистый ответ, который не предполагает какого-либо переопределения или реализации вещей..
В пакете quiver есть расширяемый класс List под названием 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)