停止方法调用 :after
Stopping the method from calling :after
假设我的代码设置如下所示
(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
)
现在假设我想将我的 space 船移到一个站点,但燃料计算导致船上的燃料量为负(即没有足够的燃料用于旅行)。
我有没有办法防止 :after
限定符被调用而不必发出错误信号?
如果我不停止呼叫,船将被移动到新位置而不会减去任何燃料,这基本上会破坏游戏。
你可以把燃料计算放在一个:AROUND
方法中,把两个:AFTER
方法变成主要方法。 :AROUND
方法必须使用 CALL-NEXT-METHOD
手动调用主要方法,因此您可以像 (when (sufficient-fuel) (call-next-method))
那样仅在燃料充足时才调用它。
请注意,条件 不一定是错误。错误是一种特定情况,其中 如果没有某种形式的干预,正常的程序执行将无法继续正确进行。
条件系统也可用于其他情况。
Common Lisp 还有 catch
和 throw
用于非本地控制转移。 throw 将在其 dynamic extent 内被 catch 捕获,使用特定的 抓标签.
外层 :around
方法为标签 exit-move
.
建立出口捕捉器
(defmethod move :around (ship destination)
(catch 'exit-move (call-next-method)))
内部方法,如主要方法,可以将控制转移到上面的 catch
,方法是使用 throw
和正确的 catch 标记 exit-move
。 primary 方法将始终在 inside around 方法 中使用,因此 catch 标记 将始终是可抛出的来自它。
(defmethod move (ship destination)
(print (list :primary ship destination))
(when (thing-happened-p)
(throw 'exit-move nil)))
假设我的代码设置如下所示
(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
)
现在假设我想将我的 space 船移到一个站点,但燃料计算导致船上的燃料量为负(即没有足够的燃料用于旅行)。
我有没有办法防止 :after
限定符被调用而不必发出错误信号?
如果我不停止呼叫,船将被移动到新位置而不会减去任何燃料,这基本上会破坏游戏。
你可以把燃料计算放在一个:AROUND
方法中,把两个:AFTER
方法变成主要方法。 :AROUND
方法必须使用 CALL-NEXT-METHOD
手动调用主要方法,因此您可以像 (when (sufficient-fuel) (call-next-method))
那样仅在燃料充足时才调用它。
请注意,条件 不一定是错误。错误是一种特定情况,其中 如果没有某种形式的干预,正常的程序执行将无法继续正确进行。 条件系统也可用于其他情况。
Common Lisp 还有 catch
和 throw
用于非本地控制转移。 throw 将在其 dynamic extent 内被 catch 捕获,使用特定的 抓标签.
外层 :around
方法为标签 exit-move
.
(defmethod move :around (ship destination)
(catch 'exit-move (call-next-method)))
内部方法,如主要方法,可以将控制转移到上面的 catch
,方法是使用 throw
和正确的 catch 标记 exit-move
。 primary 方法将始终在 inside around 方法 中使用,因此 catch 标记 将始终是可抛出的来自它。
(defmethod move (ship destination)
(print (list :primary ship destination))
(when (thing-happened-p)
(throw 'exit-move nil)))