Pharo Smalltalk LinkedList 可能异常

Posted

技术标签:

【中文标题】Pharo Smalltalk LinkedList 可能异常【英文标题】:Pharo Smalltalk LinkedList possible anomaly 【发布时间】:2019-06-18 08:38:27 【问题描述】:

我认为在实现 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 个。

【问题讨论】:

这是预期的行为。请参阅#at:putLink: 中的评论,上面写着请不要放置已在列表中的链接,否则会造成无限循环。将#at:put: 视为此类中的私有。 我不知道...它在“访问”协议中,而不是在“私有”协议中。 'at: put:' 方法 (Pharo 7) 上没有 cmets。 我认为这是“异常”。该方法应归类为私有。 但是您是否知道任何建立我所指出的这种行为的链表规范? LinkedList 预计将高效支持插入和删除消息,例如 #add:#add:before:#add:after:addFirst:#remove:#removeFirst#removeLast。它还有望支持一些枚举消息,例如#do:,您可以从中派生用于选择、拒绝和收集的消息。客户端不应该使用低级消息,例如#at:put:。事实上,LinkedList抽象的全部意义在于让客户不必关心实现细节。 【参考方案1】:

让我们总结一下 cmets 中的内容。

    LinkedList 是一个SequenceableCollection,针对在任何位置的插入和删除(元素)进行了优化。

    LinkedList 中的元素会自动包裹在ValueLink 对象中,这些对象将原始对象保存在其value ivar 中,并且可以链接到列表中的下一个元素(如果有)。当LinkedList 收到以下任何消息时会发生这种情况:

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

    接受常规对象和Links作为参数。

    另外两个公开消息提供了添加是:

    add:afterLink:addBeforeLink:

    移除元素的协议包括:

    remove:ifAbsent:removeAllremoveAllSuchThat:removeFirstremoveLast

    remove:removeAllSuchThat: 都是 双重,因为要删除的元素可以是包裹在 Link 中的对象,也可以是 Link 本身。 remove:等其他方法继承自SquenceableCollection或以上。

    枚举的方法是集合的常用方法(所有这些方法都基本上派生自 #do:),并且再次是对偶的(见上文)。

其他访问方法,如at:put:at:putLink:atLink: 等应考虑private,因为它们依赖于客户端不关心的实现细节。


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

s add: x before: s lastLink

而不是s at: 4 put: x

【讨论】:

以上是关于Pharo Smalltalk LinkedList 可能异常的主要内容,如果未能解决你的问题,请参考以下文章

Pharo Smalltalk - 消息转发,是不是可以截获消息并将其重定向到另一个对象(实例)?

如何使用Pharo中的浏览器创建软件包?

java LinkedLis t的26种使用方法

回到未来:Smalltalk 编程系统

哪些编程语言(除了 Smalltalk)是基于图像的? [关闭]

将代码从 Python 转换为 Smalltalk