如何在不评估指针的情况下从对象引用中读取槽
How to read a slot from an object reference, without evaluating the pointer
我想从另一个对象中的指针获取属性的值,但是在不评估引用的情况下访问它得到了错误
When attempting to read the slot's value (slot-value), the slot
POS is missing from the object *NODE-1*.
下面是一段模拟错误的代码:
(defclass node ()
((pos
:initarg :pos
:initform '(0 0)
:accessor pos)))
(defclass edge ()
((vertices
:initarg :vertices
:accessor vertices)))
(defparameter *node-1* (make-instance 'node))
(defparameter *node-2* (make-instance 'node :pos '(100 100)))
(defparameter *edge-1* (make-instance 'edge :vertices '(*node-1* *node-2*)))
之后,计算这个表达式会抛出错误
(slot-value (car (slot-value *edge-1* 'vertices)) 'pos)
但是这个有预期的行为
(slot-value (eval (car (slot-value *edge-1* 'vertices))) 'pos)
我已经知道 eval
用于丑陋的黑客攻击,这就是为什么我试图找到一种聪明的方法来完成我需要的事情。
When attempting to read the slot's value (slot-value), the slot
POS
is missing from the object *NODE-1*
*node-1*
不是 CLOS 实例。这是一个象征。 slot-value
需要一个 CLOS 实例。因此,尝试计算符号的 slot-value 是没有意义的。
旁注:objects
Common Lisp
在错误信息中,术语object *NODE-1*
表示运行时的特定符号对象。符号也是对象。它们不是 CLOS 对象,也就是说它们不是 CLOS class 的 CLOS 实例。但通常,即使是符号或字符串在 Common Lisp 中也被视为 objects.
为什么是符号?
您将 vertices
插槽设置为 '(*node-1* *node-2*)
的值。这是两个符号的文字列表,因为您已经引用了该列表。
CL-USER 152 > '(*node-1* *node-2*)
(*NODE-1* *NODE-2*)
CL-USER 153 > (mapcar #'type-of *)
(SYMBOL SYMBOL)
直接使用对象
如果要计算这些符号的实际值列表作为变量,则需要计算计算值列表:
CL-USER 154 > '((+ 1 2))
((+ 1 2))
CL-USER 155 > (list (+ 1 2))
(3)
CL-USER 160 > (list *node-1* *node-2*)
(#<NODE 402032A2C3> #<NODE 402032B98B>)
CL-USER 161 > (mapcar #'type-of *)
(NODE NODE)
函数 list
创建一个新列表,其参数作为内容。
获取符号的值:使用SYMBOL-VALUE
(symbol-value '*node-1*)
我想从另一个对象中的指针获取属性的值,但是在不评估引用的情况下访问它得到了错误
When attempting to read the slot's value (slot-value), the slot
POS is missing from the object *NODE-1*.
下面是一段模拟错误的代码:
(defclass node ()
((pos
:initarg :pos
:initform '(0 0)
:accessor pos)))
(defclass edge ()
((vertices
:initarg :vertices
:accessor vertices)))
(defparameter *node-1* (make-instance 'node))
(defparameter *node-2* (make-instance 'node :pos '(100 100)))
(defparameter *edge-1* (make-instance 'edge :vertices '(*node-1* *node-2*)))
之后,计算这个表达式会抛出错误
(slot-value (car (slot-value *edge-1* 'vertices)) 'pos)
但是这个有预期的行为
(slot-value (eval (car (slot-value *edge-1* 'vertices))) 'pos)
我已经知道 eval
用于丑陋的黑客攻击,这就是为什么我试图找到一种聪明的方法来完成我需要的事情。
When attempting to read the slot's value (slot-value), the slot
POS
is missing from the object*NODE-1*
*node-1*
不是 CLOS 实例。这是一个象征。 slot-value
需要一个 CLOS 实例。因此,尝试计算符号的 slot-value 是没有意义的。
旁注:objects
Common Lisp
在错误信息中,术语object *NODE-1*
表示运行时的特定符号对象。符号也是对象。它们不是 CLOS 对象,也就是说它们不是 CLOS class 的 CLOS 实例。但通常,即使是符号或字符串在 Common Lisp 中也被视为 objects.
为什么是符号?
您将 vertices
插槽设置为 '(*node-1* *node-2*)
的值。这是两个符号的文字列表,因为您已经引用了该列表。
CL-USER 152 > '(*node-1* *node-2*)
(*NODE-1* *NODE-2*)
CL-USER 153 > (mapcar #'type-of *)
(SYMBOL SYMBOL)
直接使用对象
如果要计算这些符号的实际值列表作为变量,则需要计算计算值列表:
CL-USER 154 > '((+ 1 2))
((+ 1 2))
CL-USER 155 > (list (+ 1 2))
(3)
CL-USER 160 > (list *node-1* *node-2*)
(#<NODE 402032A2C3> #<NODE 402032B98B>)
CL-USER 161 > (mapcar #'type-of *)
(NODE NODE)
函数 list
创建一个新列表,其参数作为内容。
获取符号的值:使用SYMBOL-VALUE
(symbol-value '*node-1*)