如何创建结构的深层副本

时间:2013-07-03 18:23:12

标签: lisp common-lisp structure shallow-copy

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

(defstruct state board player previous-move depth)

Board是一个二维数组。我试过了:

(setf new-state state)

当我更改new-state中的内容时,2维数组中的更改也会出现在state中。 如何创建state等结构的副本并单独更改?

2 个答案:

答案 0 :(得分:4)

Common Lisp为您提供了两种方式:

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

  • 函数COPY-STRUCTURE复制结构

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

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

答案 1 :(得分: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相同的方式使用它,即(deep-copy my-lisp-object) -> my-lisp-object-copy。但是请注意,此方法只是所需的几种方法之一,因为深度复制需要遍历结构插槽中的对象,这些对象中的对象等,直到到达最底端的不可变对象为止。如果需要,这些其他方法也包含在https://codereview.stackexchange.com/questions/156392/generic-copy-function的帖子中。 (还要注意,我已经将方法的名称从ucopy更改为深度复制,即通用复制)。祝你好运!