代码之家  ›  专栏  ›  技术社区  ›  Electric Coffee

停止方法调用:之后

  •  2
  • Electric Coffee  · 技术社区  · 8 年前

    假设我有一个类似下面的代码设置

    (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 限定符不需要发送错误条件就可以被调用?

    2 回复  |  直到 8 年前
        1
  •  4
  •   jkiiski    8 年前

    您可以将燃油计算放入 :AROUND 方法并将其转换为两个 :AFTER 方法转换为主要方法。 :周围 CALL-NEXT-METHOD 手动调用主方法,因此可以执行以下操作 (when (sufficient-fuel) (call-next-method)) 只有在有足够的燃料时才调用它。

        2
  •  2
  •   Rainer Joswig mmmmmm    8 年前

    请注意 条件 不一定是 错误 。错误是一种特定条件,其中 如果没有某种形式的干预,正常的程序执行就无法正常继续 . 这个 可用于其他 情况

    Common Lisp也有 catch throw 用于非本地控制传输。这个 将被一个 ,在其内部 动态范围 ,使用特定 catch标签 .

    外部 :around 方法为标记建立出口捕捉器 exit-move .

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

    内部方法,如主要方法,可以将控制权转移到上面 接住 ,通过使用 带有正确的catch标签 退出移动 。将始终使用主要方法 在…内 环绕法 ,因此 catch标签 总是会被扔掉。

    (defmethod move (ship destination)
      (print (list :primary ship destination))
      (when (thing-happened-p)
       (throw 'exit-move nil)))