3

如何在 Common Lisp 中复制结构?我创建了一个结构,如:

(defstruct state board player previous-move depth)

Board 是一个二维数组。我试着做:

(setf new-state state)

当我更改某些内容时new-state,二维数组中的更改也会发生在state. 如何创建结构的副本state并独立更改它?

4

3 回答 3

4

Common Lisp 提供了两种方法:

  • 定义了DEFSTRUCT state一个函数copy-state

  • 该函数COPY-STRUCTURE复制一个结构

请注意,这些是浅拷贝。只有插槽引用被复制。不会有引用数据的副本。

要复制数组,您需要编写一个例程(可能有库例程)。

于 2013-07-03T18:32:29.063 回答
0

以下通用方法可能会起作用(即,生成结构对象的深层副本),尽管它不能保证在每个 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,即通用副本)。祝你好运!

于 2019-03-28T04:02:15.493 回答
0

如果您对自动生成的结构类型不满意,另一种方法是为结构类型编写自己的复制功能。为此,您首先必须告诉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))))
于 2022-02-02T11:20:19.297 回答