簡體   English   中英

如何從對象引用中讀取插槽而不評估指針

[英]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用於丑陋的駭客,這就是為什么我試圖找到一種聰明的方法來做我需要的事情。

嘗試讀取插槽的值(插槽值)時,對象*NODE-1*缺少插槽POS

*node-1*不是CLOS實例。 這是一個象征。 slot-value需要一個CLOS實例。 因此,嘗試計算符號的槽值沒有任何意義。

旁注:Common Lisp中的objects

在錯誤消息中,術語對象 *NODE-1*表示運行時的特定符號對象。 符號也是對象。 它們不是CLOS對象,也就是說,它們不是CLOS類的CLOS實例。 但通常在Common Lisp中甚至將符號或字符串也視為對象

為什么是符號?

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

(symbol-value '*node-1*)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM