common-lisp - 常见的 LISP : convert (unknown) struct object to plist?

标签 common-lisp

(defstruct (mydate (:constructor make-mydate (year month day)))
  (year 1970)
  (month 1)
  (day 1))

 (defvar *date1* (make-mydate 1992 1 1))

这个问题更普遍,但假设我想将像 date1 这样的对象转换为我可以持久保存到数据库的“文档”(例如 mongoDB,使用包 cl-mongo)。所以我写

(defun mydate->document (mydate)
   (cl-mongo:$ (cl-mongo:$ "year" (mydate-year mydate))
               (cl-mongo:$ "month" (mydate-month mydate))
               (cl-mongo:$ "day" (mydate-day mydate))))

REPL--> (mydate->doc *date1*)
kv-container : #(#S(CL-MONGO::PAIR :KEY year :VALUE 1992)
                 #S(CL-MONGO::PAIR :KEY month :VALUE 1)
                 #S(CL-MONGO::PAIR :KEY day :VALUE 1))

但是我可以不用写下我的结构的所有字段,而是以编程方式获取它们的名称和值吗?毕竟,我的 lisp 运行时可以做到这一点:

REPL--> (describe *date1*)
#S(MYDATE :YEAR 1992 :MONTH 1 :DAY 1)
  [structure-object]

Slots with :INSTANCE allocation:
YEAR   = 1992
MONTH  = 1
DAY    = 1

另一方面,我没有在任何书中找到任何相关内容,而且我注意到库 cl-json 不能将结构转换为 JSON 格式(即使它确实转换列表和 CLOS 对象)。我想如果有一个将结构体转换成plist的函数,问题就迎刃而解了。

最佳答案

没有可移植的方式。

实现方式不同。可能大多数都有办法访问插槽的名称。我不清楚为什么标准中缺少此类功能。

例如 LispWorks 有:

(structure:structure-class-slot-names (find-class 'some-structure-class))

也许某处已经有一个兼容性库。将 CLOS 的元对象协议(protocol)功能也用于结构类是有意义的。

SBCL:

* (sb-mop:class-slots (find-class 'foo))

(#<SB-PCL::STRUCTURE-EFFECTIVE-SLOT-DEFINITION A>
 #<SB-PCL::STRUCTURE-EFFECTIVE-SLOT-DEFINITION B>)

* (mapcar 'sb-mop:slot-definition-name *)

(A B)

关于common-lisp - 常见的 LISP : convert (unknown) struct object to plist?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22084260/

相关文章:

common-lisp - 使用 SLIME 在 Aquamacs 中编译 SBCL defun 时出现类型错误

common-lisp - 在 Common Lisp 中以宏列表作为参数的宏

list - 常用 lisp 函数中的表达式和算术

lisp - 相当于 LIST 的 LISP 'subst' 函数

string - 测试普通 lisp 中的非标准 ascii 字符

common-lisp - Clozure CL 编译的可执行文件丢失某些命令行参数

common-lisp - 删除列表中的所有重复列表。口齿不清

lisp - 被 Lisp 列表比较搞糊涂了

lisp - 这段代码的功能是什么?

common-lisp - 从循环列表中删除自引用