如何将关键字转换为适合访问插槽的符号?

sbe*_*ezb 5 common-lisp

我有一个有很多插槽的课程.我还有一个构建器函数来创建该类的对象,以便将以下列表传递'(:id "john" :name "John Doe" :age 42)给该函数将构造具有这些插槽值的新对象.我将使用该函数使用列表列表生成多个对象.

如何将关键字转换为可以使用:id的插槽名称SLOT-VALUE

谢谢.

Rai*_*wig 10

如果关键字是该类的initargs,那么您可以MAKE-INSTANCE通过APPLY以下方式调用:

(defclass person ()
  ((id   :initarg :id  )
   (name :initarg :name)
   (age  :initarg :age )))


CL-USER > (mapcar
           (lambda (initargs)
             (apply #'make-instance 'person initargs))
           '((:id "john" :name "John Doe" :age 42)
             (:id "mary" :name "Mary Doe" :age 42)))

(#<PERSON 402027AB7B> #<PERSON 402027AC33>)
Run Code Online (Sandbox Code Playgroud)

  • @WhiteCat关于如何用这些列表调用`make-instance`是你的问题?我不同地理解你的问题,因为问题的标题和正文说"如何将关键字转换为适合访问插槽的符号?" 和"如何从关键字转换为:id到'SLOT-VALUE`可以使用的插槽名称?".如果你的真正目标只是调用`make-instance`而不是`slot-value`,那么Rainer Joswig的解决方案就是一种方法. (3认同)
  • @dkim:我的问题完全和你写的一样,你的回答是正确的.我之前尝试过`(find-symbol ...)`但是使用KEYWORD作为包,所以它不起作用.Rainer的回答给了我另一个视角,一个我没有考虑的视角,哪个是正确的解决方案.谢谢两位. (2认同)

dki*_*kim 5

和功能将对您有所帮助find-symbolsymbol-name如果defclassslot-value发生在同一个包中,您可以按如下方式使用这些函数:

(defclass person ()
  ((id :initarg :id)
   (name :initarg :name)
   (age :initarg :age)))

(slot-value (make-instance 'person :id "john" :name "John Doe" :age 42)
            (find-symbol (symbol-name :id)))
Run Code Online (Sandbox Code Playgroud)

如果defclassslot-value发生在两个不同的包中,则需要给出发生的find-symbol包的名称defclass

(in-package #:common-lisp-user)

(defpackage #:foo
  (:use #:common-lisp)
  (:export #:person))

(defpackage #:bar
  (:use #:common-lisp #:foo))

(in-package #:foo)

(defclass person ()
  ((id :initarg :id)
   (name :initarg :name)
   (age :initarg :age)))

(in-package #:bar)

(slot-value (make-instance 'person :id "john" :name "John Doe" :age 42)
            (find-symbol (symbol-name :id) 'foo))
Run Code Online (Sandbox Code Playgroud)

(find-symbol name &optional (package (sane-package)))

功能:返回PACKAGE中名为STRING的符号。如果找到这样的符号,则第二个值为 :INTERNAL、:EXTERNAL 或 :INHERITED,以指示如何访问该符号。如果没有找到符号,则两个值均为 NIL。

(symbol-name symbol)

功能:以字符串形式返回 SYMBOL 的名称。