Lisp 如何创建结构的深度副本

Lisp 如何创建结构的深度副本,lisp,common-lisp,structure,shallow-copy,Lisp,Common Lisp,Structure,Shallow Copy,如何在Common Lisp中复制结构?我创建了如下结构: (defstruct state board player previous-move depth) 电路板是一个二维阵列。我试着做: (setf new-state state) 当我在新状态中更改某些内容时,二维数组中的更改也会在状态中发生。 如何创建类似于state的结构副本并独立更改它?Common Lisp提供了两种方法: 使用DEFSTRUCT状态定义了一个函数复制状态 函数COPY-STRUCTURE复制结构 请注

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

(defstruct state board player previous-move depth)
电路板是一个二维阵列。我试着做:

(setf new-state state)
当我在
新状态
中更改某些内容时,二维数组中的更改也会在
状态
中发生。
如何创建类似于
state
的结构副本并独立更改它?

Common Lisp提供了两种方法:

  • 使用
    DEFSTRUCT
    状态
    定义了一个函数
    复制状态

  • 函数
    COPY-STRUCTURE
    复制结构

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


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

Common Lisp提供了两种方法:

  • 使用
    DEFSTRUCT
    状态
    定义了一个函数
    复制状态

  • 函数
    COPY-STRUCTURE
    复制结构

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


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

以下通用方法可能有效(即,生成结构对象的深度副本),尽管它不能保证在每个常见的Lisp实现中都有效,而且肯定不可移植。它不符合常见的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))

使用它的方式与使用
复制列表
——即
(深度复制我的lisp对象)->我的lisp对象复制
的方式相同。但是请注意,此方法只是所需的几种方法之一,因为深度复制需要在结构插槽中的对象、这些对象中的对象等上递归,直到到达最底层的不可变对象为止。如果需要,这些其他方法将包含在post at中。(还要注意,我已经将方法的名称从ucopy ie,universal copy更改为deep copy)。祝你好运

以下通用方法可能有效(即,生成结构对象的深度副本),尽管它不能保证在每个常见的Lisp实现中都有效,而且肯定不可移植。它不符合常见的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))

使用它的方式与使用
复制列表
——即
(深度复制我的lisp对象)->我的lisp对象复制
的方式相同。但是请注意,此方法只是所需的几种方法之一,因为深度复制需要在结构插槽中的对象、这些对象中的对象等上递归,直到到达最底层的不可变对象为止。如果需要,这些其他方法将包含在post at中。(还要注意,我已经将方法的名称从ucopy ie,universal copy更改为deep copy)。祝你好运

我正在做一个夏威夷跳棋游戏,使用minimax。我需要在不改变国家的情况下,建立一个国家并创造它的继任者。还有吗?@FredPT:?我刚才给了你两种复制结构的方法。使用
alexandria:copy array
复制数组。这篇文章仍然没有回答如何获得深度复制的问题。我正在用minimax做夏威夷跳棋游戏。我需要在不改变国家的情况下,建立一个国家并创造它的继任者。还有吗?@FredPT:?我刚才给了你两种复制结构的方法。使用
alexandria:copy array
复制数组。这篇文章仍然没有回答如何获得深度复制的问题。