尝试删除第一个对象时,如何在 Smalltalk 中捕获一个空的 LinkedList 异常?
When trying to remove first object, how can I catch an empty LinkedList exception in Smalltalk?
我是 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>]
更一般地说,参数 Error
可以替换为 Exception
层次结构的任何子类,这意味着您的代码将只处理某些类型的异常。
异常处理是 Smalltalk 中的一个广泛主题,因此将此答案视为帮助您编写一些初步 Smalltalk 代码的提示。
编辑
@SeanDeNigris 的回答和评论让我意识到我的回答至少在一个方面是不完整的:我们如何确定列表的第一个元素?事实上,使用 remove:ifAbsent:
的表达式没有说明第一个参数,原始问题将其标识为第一个元素。为了完成答案,我们还必须解决这个问题。
在第一次尝试中,我们可以尝试:
^aLinkedList remove: aLinkedList first ifAbsent: [nil]
但问题是,如果列表恰好为空,消息 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:
块中
但是...除非您将此作为类似型的练习,否则有时使用 "if" 是可以的!在您的 Python 示例中,系统似乎为您提供了一些内置支持,在 Smalltalk 中可能类似于 #removeFirstUnlessEmpty
(您可以实现以隐藏丑陋)。一旦你不得不求助于异常,我不会说这比使用 if.
如果它让你感觉好点,在 Smalltalk 中 #ifTrue: 是一条消息,而不是一条语句,所以它不会影响你的代码的纯度......除非你嵌套它们,这很糟糕味道 ;)
我是 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>]
更一般地说,参数 Error
可以替换为 Exception
层次结构的任何子类,这意味着您的代码将只处理某些类型的异常。
异常处理是 Smalltalk 中的一个广泛主题,因此将此答案视为帮助您编写一些初步 Smalltalk 代码的提示。
编辑
@SeanDeNigris 的回答和评论让我意识到我的回答至少在一个方面是不完整的:我们如何确定列表的第一个元素?事实上,使用 remove:ifAbsent:
的表达式没有说明第一个参数,原始问题将其标识为第一个元素。为了完成答案,我们还必须解决这个问题。
在第一次尝试中,我们可以尝试:
^aLinkedList remove: aLinkedList first ifAbsent: [nil]
但问题是,如果列表恰好为空,消息 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:
块中
但是...除非您将此作为类似型的练习,否则有时使用 "if" 是可以的!在您的 Python 示例中,系统似乎为您提供了一些内置支持,在 Smalltalk 中可能类似于 #removeFirstUnlessEmpty
(您可以实现以隐藏丑陋)。一旦你不得不求助于异常,我不会说这比使用 if.
如果它让你感觉好点,在 Smalltalk 中 #ifTrue: 是一条消息,而不是一条语句,所以它不会影响你的代码的纯度......除非你嵌套它们,这很糟糕味道 ;)