有没有一种方法可以动态地请求另一个包中的绑定,而动态地我是指不知道某个包中绑定的确切名称。一个具体的例子是:
与程序包B一样,我知道存在一个程序包A,该程序包具有某个类,并且我通过(在LispWorks中)提取该类的所有直接插槽:
(setq direct-slots (mapcar #'slot-definition-name
(class-direct-slots (class-of class-in-package-A))))
现在,我想使用MAPCAR将这些插槽绑定到某些值:
(mapcar #'(lambda (slot) (list slot
(funcall slot class-in-package-A)))
direct-slots)
这不起作用,因为我在程序包B中,并且需要程序包精度才能调用(funcall slot class-in-package-A)
,packageA::slot
显然是错误的。是否有为此功能在包装中搜索某个符号?
答案 0 :(得分:2)
如果您有插槽名称,并且想要获取某个对象中命名插槽的值,请使用slot-value
:
(mapcar (lambda (slot-name)
(slot-value some-object slot-name))
slot-names)
插槽名称是符号,如果您碰巧是在另一个封装中,它们就不会神奇地丢失其封装。我认为您的困惑是您在考虑访问器,但是那是另一回事(内部使用slot-value
之类的东西。)
CL-USER> (defpackage #:foo
(:use #:cl))
#<PACKAGE "FOO">
CL-USER> (defpackage #:bar
(:use #:cl #:sb-mop)) ; in SBCL
#<PACKAGE "BAR">
CL-USER> (in-package #:foo)
#<PACKAGE "FOO">
FOO> (defclass afoo ()
((a :initarg :a)
(b :initarg :b)))
#<STANDARD-CLASS FOO::AFOO>
FOO> (in-package #:bar)
#<PACKAGE "BAR">
BAR> (mapcar #'slot-definition-name
(class-direct-slots (find-class 'foo::afoo)))
(FOO::A FOO::B)
BAR> (let ((slot-names (mapcar #'slot-definition-name
(class-direct-slots (find-class 'foo::afoo))))
(obj (make-instance 'foo::afoo
:a 1
:b 2)))
(mapcar (lambda (slot-name)
(slot-value obj slot-name))
slot-names))
(1 2)
通常,您应该在“用户”代码中使用访问器,并且应该知道给定对象存在哪些访问器。用户代码是否为直接插槽也无关紧要。