Если у вас есть имя слота и вы хотите получить значение названного слота в каком-либо объекте, используйте 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)
Как правило, вы должны использовать средства доступа в «пользовательском» коде, и вы должны знать, какие средства доступа существуют для данного объекта. Для пользовательского кода также не должно иметь значения, является ли что-то слотом прямой .