在 common lisp 的封装 class 方法中访问封装的 class 槽
Accessing an encapsulated class slots within the encapsulating class method in common lisp
我有以下基本的class方法:
(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
class 有 nodes
,这是 Node
个对象的列表。 Node
class 有 Edge
个对象的列表。
意向:
在 Node
对象中读取/写入 forward-edges
和 backward-edges
封装在 Edge
对象(节点列表)
Problem/Question:
这 "works" 按预期返回 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))
失败。
我有以下基本的class方法:
(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
class 有 nodes
,这是 Node
个对象的列表。 Node
class 有 Edge
个对象的列表。
意向:
在 Node
对象中读取/写入 forward-edges
和 backward-edges
封装在 Edge
对象(节点列表)
Problem/Question:
这 "works" 按预期返回 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))
失败。