Data structures Pharo Smalltalk链接列表可能存在异常

Data structures Pharo Smalltalk链接列表可能存在异常,data-structures,smalltalk,pharo,Data Structures,Smalltalk,Pharo,我认为在实现at:put:LinkedList方法时存在一个bug 我在使用Stack类(LinkedList的后代)时检测到了这个问题。使用at:put:方法为列表的最后一个元素赋值时,其他元素从列表中消失。当后一个元素指向列表中已有的其他元素时,就会发生这种情况。我怀疑这是一个bug还是一个特性 s := LinkedList new. x := (NewValueHolder value: 99). s add: (NewValueHolder value: 99); a

我认为在实现at:put:LinkedList方法时存在一个bug

我在使用Stack类(LinkedList的后代)时检测到了这个问题。使用at:put:方法为列表的最后一个元素赋值时,其他元素从列表中消失。当后一个元素指向列表中已有的其他元素时,就会发生这种情况。我怀疑这是一个bug还是一个特性

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个元素。

让我们总结一下注释中的内容

  • LinkedList
    是一个
    SequenceableCollection
    优化,可在任何位置插入和删除(元素)
  • LinkedList
    中的元素自动包装在
    ValueLink
    对象中,这些对象将原始对象保存在其
    value
    ivar中,并且可以链接到列表中的下一个元素(如果有)。当
    LinkedList
    收到以下任何消息时,就会发生这种情况:

    add:
    add:after:
    add:before:
    addFirst:
    addLast:

    它接受常规对象和
    链接
    作为参数

  • 另外,还提供了两条供添加的公共消息:

    add:afterLink:
    addBeforeLink:

  • 删除元素的协议包括:

    remove:ifAbsent:
    removeAll
    removeAll:
    removeast

    remove:
    removealls:
    都是双重的,因为要删除的元素可以是包装在
    链接中的对象,也可以是
    链接本身。其他方法,如
    remove:
    继承自
    SquenceableCollection
    或更高版本

  • 枚举方法通常用于集合(所有集合基本上都源自
    #do:
    ),并且是双重的(见上文)
  • 其他访问方法,如
    at:put:
    at:putLink:
    atLink:
    等,应视为
    private
    ,因为它们依赖于客户不关心的实现细节


    回到问题,在位置4添加元素
    x
    的正确方法是

    s add: x before: s lastLink
    

    而不是
    s at:4 put:x

    这是预期的行为。请参见
    #at:putLink:
    中的注释,内容为请不要放置列表中已有的链接,否则将创建一个无限循环。考虑<代码>:把:作为本班的私人。我不知道…它在“访问”协议中,而不是在“专用”协议中。对“at:put:”方法(Pharo 7)没有任何评论。我认为这是“异常”。该方法应被分类为私有。但是您知道我所指出的建立这种行为的链表的任何规范吗?
    LinkedList
    应能有效地支持插入和删除消息,例如
    \add:
    \add:before:
    \add:after:
    addFirst:
    #remove:
    #removeFirst
    #removeLast
    。它还应该支持一些枚举消息,如
    #do:
    ,从中可以派生用于选择、拒绝和收集的消息。客户端不应该使用低级别消息,例如
    #at:put:
    。事实上,
    LinkedList
    抽象的全部要点就是让客户机不必关心实现细节。