Pharo Smalltalk LinkedList возможные аномалии - PullRequest
1 голос
/ 18 июня 2019

Я думаю, что есть ошибка в реализации метода at: put: LinkedList.

Я обнаружил проблему при использовании класса Stack, потомка LinkedList. При использовании метода at: put: для присвоения значения последнему элементу списка другие элементы исчезли из списка. Это произошло, когда последний элемент указал на какой-то другой, уже находящийся в списке. Я сомневаюсь, это ошибка или особенность.

s := LinkedList new.
x := (NewValueHolder value: 99).
s 
    add: (NewValueHolder value: 99);
    add: x;
    add: (NewValueHolder value: 99);
    add: (NewValueHolder value: 99).
s at: 4 put: x.
s

После запуска список содержит только 2 элемента, а не 4, как ожидалось.

1 Ответ

0 голосов
/ 20 июля 2019

Давайте подведем итоги, что в комментариях.

  1. A LinkedList - это SequenceableCollection, оптимизированный для вставки и удаления (элементов) в любой позиции.
  2. Элементы внутри LinkedList автоматически оборачиваются внутри ValueLink объектов, которые содержат исходный объект в их value иваре и могут быть связаны со следующим элементом в списке, если таковые имеются. Это происходит, когда LinkedList получает любое из следующих сообщений:

    add:, add:after:, add:before: addFirst: и addLast:.

    , которые принимают в качестве аргументов как обычные объекты, так и Links.

  3. Два дополнительных публичных сообщения предоставляются для добавления:

    add:afterLink: и addBeforeLink:

  4. Протокол удаления элементов состоит из:

    remove:ifAbsent:, removeAll, removeAllSuchThat:, removeFirst и removeLast

    Оба remove:, removeAllSuchThat: являются dual в том смысле, что удаляемым элементом может быть объект, завернутый в Link или сам Link. Другие методы, такие как remove:, наследуются от SquenceableCollection или выше.

  5. Методы перечисления являются обычными для коллекций (все из которых по существу происходят от #do:) и, опять же, двойственны (см. Выше).

Другие методы доступа, такие как at:put:, at:putLink:, atLink: и т. Д., Должны рассматриваться как private, так как они основаны на деталях реализации, которые не касаются клиентов.


Возвращаясь к вопросу, правильный способ добавить элемент x в позицию 4 был бы

s add: x before: s lastLink

вместо s at: 4 put: x.

...