2

假设我有如下代码设置

(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限定符被调用而不必发出错误信号?

如果我不停止通话,船将被移动到新位置而不会减去任何燃料,这基本上会破坏游戏。

4

2 回答 2

4

您可以将燃料计算放入一个:AROUND方法中,并将这两种:AFTER方法转换为主要方法。:AROUND方法必须CALL-NEXT-METHOD手动调用主方法,所以你可以做一些事情,比如(when (sufficient-fuel) (call-next-method))只有在有足够的燃料时才调用它。

于 2016-08-18T11:39:00.033 回答
2

请注意,条件不一定是错误。错误是一种特定情况,在这种情况下,如果没有某种形式的干预,正常的程序执行将无法正确继续条件系统也可以用于其他情况

Common Lisp 也有catchthrow用于非本地控制转移。投掷将在其动态范围内使用特定的接球标记接球接住。

外部:around方法为标签建立了一个出口捕手exit-move

(defmethod move :around (ship destination)
  (catch 'exit-move (call-next-method)))

内部方法,就像主要方法一样,可以catch通过使用throw正确的 catch 标记将控制权转移到上面exit-move。primary 方法将始终在 around 方法中使用因此catch标记始终可以从中抛出。

(defmethod move (ship destination)
  (print (list :primary ship destination))
  (when (thing-happened-p)
   (throw 'exit-move nil)))
于 2016-08-20T10:34:59.670 回答