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

Exception handling 尝试删除第一个对象时,如何在Smalltalk中捕获空LinkedList异常?,exception-handling,linked-list,smalltalk,Exception Handling,Linked List,Smalltalk,我是Smalltalk的新手,尽量不使用if语句! 关于Python,我将写: try: element = LinkedList.remove() except: element = "nil" finally: return element Smalltalk中的等价物是什么?简短回答: ^aLinkedList remove: aLinkOrObject ifAbsent: [nil] 请注意,在Smalltalk中,所有支持删除元素的集合也支持remove:ifAb

我是Smalltalk的新手,尽量不使用if语句! 关于Python,我将写:

try:
   element = LinkedList.remove()
except:
   element = "nil"
finally:
   return element
Smalltalk中的等价物是什么?

简短回答:

^aLinkedList remove: aLinkOrObject ifAbsent: [nil]
请注意,在Smalltalk中,所有支持删除元素的集合也支持
remove:ifAbsent:
消息。第一个参数是要删除的元素,第二个参数是处理元素不在集合中的情况的块

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

[<Smalltalk expression>] on: Error do: [:ex | <handle ex>]
但问题是,如果列表恰好为空,则消息
aLinkedList first
将发出错误信号。换句话说,
ifAbsent:
部分将是无用的。因此,正如肖恩所说,我们只有两种选择。在第一种情况下,我们使用条件逻辑来区分列表是否为空:

^aLinkedList isEmpty
    ifTrue: [nil]
    ifFalse: [aLinkedList remove: aLinkedList first]
第二种选择是使用异常:

^[aLinkedList remove: aLinkedList first] on: Error do: [nil]

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

正如Leandro所说,您问题的字面答案是将语句包装在
on:do:
块中

但是。。。除非你是作为一种类似于kata的运动来做,否则有时候可以用“如果”!在您的Python示例中,系统似乎为您提供了一些内置支持,在Smalltalk中可能类似于
#removeFirstUnlessEmpty
(您可以实现它来隐藏丑陋之处)。一旦你不得不求助于异常,我不会说这比使用if要好


如果它能让你感觉更好,在Smalltalk中,如果真的是这样的话:它是一条信息,而不是一条语句,所以它不会影响你代码的纯度。。。除非你把它们放在窝里,这只是低级趣味;)

@Seandeegris这是一个很好的观点。有时,一个简单的IF比处理异常要好得多,尤其是当代码可以很容易地预测这样的事件时。但是请注意,
remove:ifAbsent:
正是这样做的,它使
remove:
的发送者不必以自己的方式编写条件逻辑。True re#remove:ifAbsent:,但用例是#removeFirst,其中建议的方法要求您事先了解对象,即使它是第10项,no?+1,也会删除它,尽管我会重构
ifTrue:ifFalse:
块中的返回,即:
^aLinkedList isEmpty ifTrue:[nil]ifFalse:[aLinkedList remove:aLinkedList first]
。我也同意@Sean的观点,将所有这些重构成一个单独的方法会更干净,而且
#removeFirstUnlessEmpty
是一个好的、清晰的名字,它将阻止下一个peson想要重新发明轮子。我也更喜欢一个块外的返回。我不是这样写的,因为这个问题是由一个初学者提出的,而将回报分解出来要高级一点。事实上,我也会取消
ifTrue:[nil]
分支(即使这不符合ANSI标准)。
ifTrue:[nil]
并不太糟糕,因为它更明确地揭示了其意图
^[aLinkedList remove: aLinkedList first] on: Error do: [nil]