在尝试删除第一个对象时,如何在Smalltalk中捕获空的LinkedList异常?

Agu*_*ina 4 smalltalk exception-handling linked-list

我是Smalltalk的新手,并试图不使用if语句!在Python上我会写:

try:
   element = LinkedList.remove()
except:
   element = "nil"
finally:
   return element
Run Code Online (Sandbox Code Playgroud)

Smalltalk中的等价物是什么?

Lea*_*lia 7

简短回答:

^aLinkedList remove: aLinkOrObject ifAbsent: [nil]
Run Code Online (Sandbox Code Playgroud)

请注意,在Smalltalk中,支持删除元素的所有集合也支持该remove:ifAbsent:消息.第一个参数是要删除的元素,第二个参数是一个块,用于处理元素不在集合中的情况.

更一般地说,处理Smalltalk异常的方法遵循以下模式:

[<Smalltalk expression>] on: Error do: [:ex | <handle ex>]
Run Code Online (Sandbox Code Playgroud)

更一般地说,参数Error可以替换为Exception层次结构的任何子类,这意味着您的代码只能处理某些类型的异常.

异常处理是Smalltalk中的一个主题,因此请将此答案作为一个提示来帮助您编写一些初步的Smalltalk代码.

编辑

@SeanDeNigris的回答和评论使我意识到我的答案至少在一个方面是不完整的:我们如何确定列表的第一个元素?实际上,使用的表达式remove:ifAbsent:对第一个参数没有任何说明,原始问题将其标识为第一个元素.要完成答案,我们还必须解决此问题.

在第一次尝试中,我们可以尝试:

^aLinkedList remove: aLinkedList first ifAbsent: [nil]
Run Code Online (Sandbox Code Playgroud)

但问题是aLinkedList first如果列表恰好为空,则消息将发出错误信号.换句话说,这ifAbsent:部分将是无用的.所以,正如肖恩所说,我们有两种选择.在第一个中,我们使用条件逻辑来区分列表是否为空:

^aLinkedList isEmpty
    ifTrue: [nil]
    ifFalse: [aLinkedList remove: aLinkedList first]
Run Code Online (Sandbox Code Playgroud)

第二种选择包括使用例外:

^[aLinkedList remove: aLinkedList first] on: Error do: [nil]
Run Code Online (Sandbox Code Playgroud)

在这一点上,我们面临的问题是哪种选择更好.适用的一个好标准是简单性.哪种解决方案更简单?显然是第一个.错误处理是一种使用一些非平凡机器的高级功能.第一种解决方案依赖于基本条件逻辑.此外,如果我们事先知道如果列表为空,那么唯一预期的错误将会发生,那么假装我们无法预料到异常的重点是什么.在这方面,例外的使用on:do:是过度的,我们应该在这里避免它.