Как мне расширить список в дартс?

Я хочу создать более специализированный список в дартс. Я не могу напрямую расширить список. Какие у меня варианты?

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
}
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
}

В зависимости от вашего кода каждый из этих вариантов имеет свои преимущества. Если вы переносите / делегируете существующий список, вы должны использовать последний вариант. В противном случае используйте один из двух первых вариантов в зависимости от вашей иерархии типов (миксин, позволяющий расширить другой объект).

Новый способ расширения классов был представлен в 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)
Другие вопросы по тегам