我正在尝试通过另一个结构实例或其名称访问结构实例的字段。由于这听起来非常令人困惑,我有一个(非常构造的)例子:
(defstruct author
(name nil)
(books '())
(years '()))
(defstruct book
(name nil)
(author '())
(copy-sold '()))
(defparameter hitchikers-guide
(make-book :name "Hitchikers-Guide"
:author '(douglas-adams)
:copy-sold '(a lot)))
(defparameter douglas-adams
(make-author :name "Douglas Adams"
:books '(Hitchikers-guide restaurant life-and-universe fish)
:years '(too few)))
(defparameter authors
'(douglas-adams pterry))
我有实例hitchikers-guide
。如果我想查找其作者的所有书籍,我可以输入REPL (author-books douglas-adams)
,我会得到他所有书籍的清单。但是,如果我输入
(author-books (first (book-author hitchikers-guide)))
或
(author-books (first authors))
我收到错误消息:
值DOUGLAS-ADAMS不是预期类型AUTHOR。
我做错了,还是没办法以这种方式访问这些字段?
答案 0 :(得分:5)
您的变量authors
包含symbol
s,而不是author
s。
尝试
(defparameter authors (list douglas-adams pterry))
相反(如果已经定义了cource,pterry
)。
同样,(book-author hitchikers-guide)
是symbol
的列表,而不是author
。
您需要使用symbol-value
来获取相应的author
。
答案 1 :(得分:4)
如果您想通过符号查找对象作为其标识符,则需要使用数据结构。
简单版本在包中使用符号。
(defun find-object (name)
(symbol-value name))
(defun intern-object (object name)
(setf (symbol-value name) object))
但你也可以使用哈希表:
(defvar *my-objects* (make-hash-table))
(defun find-object (name)
(gethash name *my-objects*))
(defun intern-object (object name)
(setf (gethash name *my-objects*) object))
答案 2 :(得分:1)
首先是作者还是书?
;; first the author
(defstruct (author :conc-name make-author-internal)
(name nil)
(books '())
(years '()))
(defun make-author (name years)
(make-author-internal :name name :books '() :years years))
(defun author-add-book (author book)
(setf (author-books author)
(cons book (author-books author))))
;; now the book, requires an author (assumes one, if >1, use a list)
(defstruct (book :conc-name make-book-internal)
(name nil)
(author nil)
(copy-sold '()))
(defun make-book (name author copy-sold)
(let ((book (make-book-internal :name name :author author ...)))
(author-add-book author book)
book))
;; ...
(defparameter douglas-adams
(make-author "Douglas Adams" ...))
(defparameter hitchikers-guide
(make-book "Hitchikers-Guide" douglas-adams ...))