首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CLOS插槽访问器:读但不写

CLOS插槽访问器:读但不写
EN

Stack Overflow用户
提问于 2014-06-20 20:20:54
回答 2查看 569关注 0票数 0

我有一个CLOS对象的插槽名称列表:

代码语言:javascript
复制
(DEFCLASS TRIAL-DATA (STANDARD-OBJECT) 
 ((A-DATUM :ACCESSOR A-DATUM :INITARG :A-DATUM :INITFORM NIL) 
  (BOTH-DATA :ACCESSOR BOTH-DATA :INITARG :BOTH-DATA :INITFORM 0) 
  (CUMULATIVE-DATA :ACCESSOR CUMULATIVE-DATA :INITARG :CUMULATIVE-DATA :INITFORM NIL) 
  (NAME :ACCESSOR NAME :INITARG :NAME :INITFORM VALUE)))

(let* ((td (make-instance 'trial-data))
   (slot-lst (mapcar #'slot-definition-name (class-slots (class-of td)))))

我可以读懂这些插槽的价值:

代码语言:javascript
复制
(let* ((td (make-instance 'trial-data))
   (slot-lst (mapcar #'slot-definition-name (class-slots (class-of td)))))
(funcall (symbol-function (nth 0 slot-lst)) td))

==>零

但是为什么我不能给这些插槽写新的值呢?我对试用数据的类定义不应该为每个时隙创建一个访问器函数吗?

代码语言:javascript
复制
;; Should set the first slot, a-datum's, value to 42
(let* ((td (make-instance 'trial-data))
       (slot-lst (mapcar #'slot-definition-name (class-slots (class-of td)))))
    (setf (funcall (symbol-function (nth 0 slot-lst)) td) 42))

==>

代码语言:javascript
复制
;Compiler warnings for "/Users/frank/Documents/NRL/Error/Patrolbot/Patrol Construction Notes & Testing.lisp" :
;   In an anonymous lambda form at position 123: Undefined function (SETF FUNCALL)
> Error: Undefined function (SETF FUNCALL) called with arguments (42 #<STANDARD-GENERIC-FUNCTION A-DATUM #x302001D1C5DF> #<TRIAL-DATA #x30200200D95D>) .
> While executing: #<Anonymous Function #x30200200EB7F>, in process Listener-2(5).
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-20 21:29:55

Rainer Joswigs's answer解决了为什么不能用现在的代码来设置的问题。但是,还需要注意的是,没有理由让读者、作者或访问器名称与槽名相同,所以如果您实际得到的是槽名,那么您应该在其中使用(setf slot-value)。例如,

代码语言:javascript
复制
(defclass foo ()
  ((bar :accessor getbar :initform 42)))

(defparameter *foo* (make-instance 'foo))
代码语言:javascript
复制
;; neither of these work
(setf (bar *foo*) 34)
(funcall #'(setf bar) 34 *foo*)

(slot-value *foo* 'bar)
;=> 42

(setf (slot-value *foo* 'bar) 36)
;=> 26

(slot-value *foo* 'bar)
;=> 36
票数 2
EN

Stack Overflow用户

发布于 2014-06-20 20:47:34

访问器称为a-datum

读者:

代码语言:javascript
复制
CL-USER 9 > #'a-datum
#<STANDARD-GENERIC-FUNCTION A-DATUM 406000091C>

作者:

代码语言:javascript
复制
CL-USER 10 > #'(setf a-datum)
#<STANDARD-GENERIC-FUNCTION (SETF A-DATUM) 422000958C>

如果您想通过funcall调用编写器,则需要调用上面的函数。

如果您有一个普通的表单(setf (a-datum foo) 'bar)),那么需要在宏展开时解决这个问题。

错误消息显示#'(setf funcall)是未定义的。因此,(setf (funcall ...) ...)不存在。

在你的情况下,你是如何得到作者函数的?

代码语言:javascript
复制
CL-USER 11 > (fdefinition '(setf a-datum))
#<STANDARD-GENERIC-FUNCTION (SETF A-DATUM) 422000958C>

CL-USER 12 > (let ((name 'a-datum)) (fdefinition `(setf ,name)))
#<STANDARD-GENERIC-FUNCTION (SETF A-DATUM) 422000958C>

给你的任务:对上述功能正确的参数是什么?

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24335054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档