如何在 Common Lisp 中复制结构?我创建了一个结构,如:
(defstruct state board player previous-move depth)
Board 是一个二维数组。我试着做:
(setf new-state state)
当我更改某些内容时new-state
,二维数组中的更改也会发生在state
. 如何创建结构的副本state
并独立更改它?
如何在 Common Lisp 中复制结构?我创建了一个结构,如:
(defstruct state board player previous-move depth)
Board 是一个二维数组。我试着做:
(setf new-state state)
当我更改某些内容时new-state
,二维数组中的更改也会发生在state
. 如何创建结构的副本state
并独立更改它?
Common Lisp 提供了两种方法:
定义了DEFSTRUCT
state
一个函数copy-state
。
该函数COPY-STRUCTURE
复制一个结构
请注意,这些是浅拷贝。只有插槽引用被复制。不会有引用数据的副本。
要复制数组,您需要编写一个例程(可能有库例程)。
以下通用方法可能会起作用(即,生成结构对象的深层副本),尽管它不能保证在每个 Common Lisp 实现中都有效,当然也不是可移植的。它不符合 Common Lisp Hyperspec,因为它试图将类函数应用于结构。但个人使用可能值得一试。
(defmethod deep-copy ((struct structure-object))
"Copy a structure recursively."
(let ((new-struct (copy-structure struct))
(slots (class-direct-slots (class-of struct))))
(dolist (slot slots)
(let ((slot-name (slot-definition-name slot)))
(setf (slot-value new-struct slot-name)
(deep-copy (slot-value struct slot-name)))))
new-struct))
copy-list
以与使用--ie,相同的方式使用它(deep-copy my-lisp-object) -> my-lisp-object-copy
。但是请注意,此方法只是所需的几种方法之一,因为深拷贝需要递归遍历结构槽中的对象、这些对象中的对象等,直到到达最底部的不可变对象。如果需要,这些其他方法包含在https://codereview.stackexchange.com/questions/156392/generic-copy-function的帖子中。(还要注意,我已经将方法的名称从 ucopy 更改为 deep-copy,即通用副本)。祝你好运!
如果您对自动生成的结构类型不满意,另一种方法是为结构类型编写自己的复制功能。为此,您首先必须告诉defstruct
宏不要自动创建复制功能。
(defstruct (foo (:copier nil))
(arr (make-array 10 :initial-element 0)))
;; now you can write your custom copy-foo function
(defun copy-foo (original)
(make-foo
:arr (copy-seq (foo-arr original))))