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:
、removeAll
、removeAllSuchThat:
、removeFirst
和 removeLast
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 - 消息转发,是不是可以截获消息并将其重定向到另一个对象(实例)?