假设我有一个类似下面的代码设置
(defgeneric move (ship destination))
(defmethod move (ship destination)
;; do some fuel calculation here
)
(defmethod move :after ((ship ship) (dest station))
;; do things specific to landing on a station here
)
(defmethod move :after ((ship ship) (dest planet))
;; do things specific to landing on a planet here
)
现在让我说我想把我的太空船移到一个车站,但是燃油计算导致船上的燃油量不足(即行程不够)。
那么我是否有办法阻止:after
限定符被调用而不必发出错误信号?
如果我没有停止通话,则该船将被移至新位置而不会减去任何燃料,这实际上会破坏游戏。
答案 0 :(得分:4)
您可以使用:AROUND
方法进行燃料计算,并将两个:AFTER
方法转换为主要方法。 :AROUND
方法必须手动使用CALL-NEXT-METHOD
来调用主要方法,因此您可以执行(when (sufficient-fuel) (call-next-method))
之类的操作,只在有足够的燃料时才调用它。
答案 1 :(得分:2)
请注意,条件不一定是错误。错误是一种特定情况,其中正常程序执行无法在没有某种形式的干预的情况下正确继续。 条件系统也可以用于其他情境。
Common Lisp还有catch
和throw
用于非本地控制传输。 throw 将使用特定的 catch标记在其动态范围中由 catch 捕获。
外部:around
方法为代码exit-move
建立退出捕获器。
(defmethod move :around (ship destination)
(catch 'exit-move (call-next-method)))
内部方法与主要方法一样,可以通过使用带有正确catch标记catch
的{{1}}将控制权转移到上述throw
。主要方法将始终使用 around方法,因此 catch标记将始终可以从中抛出。
exit-move