common-lisp - 在 Common Lisp 中访问封装类方法中的封装类槽

标签 common-lisp clos

我有以下基本类和方法:

        (defgeneric connect-edge (edge))

        (defclass Node ()
          ((forward-edges :initform nil)
           (backward-edges :initform nil)
           (value :initform 0.0)))

        (defclass Edge ()
          ((value :initform 0.0)
           (nodes :initform nil)))

        (defmethod connect-edge ((edge Edge))
        ;; does nothing important. Simplified to cause the problem
            (slot-value (car (slot-value edge 'nodes)) 'forward-edges))

我简化了方法,足以给我一个错误。基本上此时它没有做任何有用的事情,但足以演示问题。

设置:

Edge 类具有 nodes,它是 Node 对象的列表。 Node 类具有 Edge 对象列表。

意图:

读取/写入封装在Edge内的Node对象中的forward-edgesbackward-edges对象(节点列表)

问题/疑问:

通过按预期返回 nil 来“起作用”:

(defparameter *edge* (make-instance 'Edge))
(setf (slot-value *edge* 'nodes) (list (make-instance 'Node) (make-instance 'Node)))
(connect-edge *edge*)

这段代码给了我下面的错误,为什么

(connect-edge (make-instance 'Edge))

There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION (SB-PCL::SLOT-ACCESSOR :GLOBAL
                               COMMON-LISP-USER::FORWARD-EDGES
                               SB-PCL::READER) (1)>
when called with arguments
  (NIL).

此外,如果我这样做,我会收到以下错误,我想我明白原因:没有定义需要 nil 的通用函数:

(connect-edge nil)

There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION COMMON-LISP-USER::CONNECT-EDGE (1)>
when called with arguments
  (NIL).
   [Condition of type SIMPLE-ERROR]

我为什么要做这一切?

我有以下代码,它会导致(可能出于不同的原因)类似的错误:

(defun make-classic (net)
  (loop
     for this-layer in net
     for next-layer in (cdr net)
     do
       (loop
      for this-node in this-layer
      do
        (loop
           for next-node in next-layer
           do
         (let ((edge (make-instance 'Edge)))
           (setf (slot-value edge 'nodes) '(this-node next-node))
           (format t "Type of edge is ~a~%" (type-of edge))
           ;; Error is here
           (connect-edge edge))))))

我不确定错误是否是由于传递作用域变量引起的,因此我最终尝试传递 (make-instance 'Edge) 来导致错误。

最佳答案

这就是您所需要的:

when called with arguments (NIL).

(slot-value (make-instance 'Edge) 'nodes)

nil,所以

 (slot-value (car (slot-value edge 'nodes)) 'forward-edges))

失败。

关于common-lisp - 在 Common Lisp 中访问封装类方法中的封装类槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48391656/

相关文章:

common-lisp - SBCL:将 Hunchentoot 应用程序部署为可执行文件

lisp - let、eval 和 quote 的行为

timer - 通用 Lisp 计时器

common-lisp - 覆盖 :INITFORM of the class slot in subclass

common-lisp - 基于 Common Lisp 对象系统类定义中的其他槽值初始化槽

functional-programming - mapcar 的多个参数

lisp - 如何在类Unix操作系统下方便的运行SBCL代码?

class - 是否可以在现有类中动态添加一个父类(super class)

inheritance - 菱形继承(钻石问题)和 Common Lisp 对象系统

common-lisp - 从使用的外部包访问 CLOS 对象槽