1

我想知道如何在 Common Lisp 中执行以下操作。假设我在内存中有一个在某个时间是唯一的对象(实体)。我想做的是将一些变量设置为该对象的状态,作为某个时间的快照。然后原始实体可能会进化。但是,我想确保该变量仍然指向该实体过去的状态。

看来我需要的是类似于深拷贝+二传手的东西。复杂的因素是,有时实体的性质是未知的。它可能是一个数组,也可能是一个哈希表。它也可以是一个对象。

任何建议表示赞赏。

4

1 回答 1

3

您唯一需要的是不可变对象并且只更新绑定。 setq(并setf以符号作为第一个参数)完美地做到了这一点。这里有些例子:

(defparameter *test* '(1 2))
(defparameter *test2* *test*) ; a copy
(setf *test* (cdr *test*))    ; *test* is (2), but *test2* is still (1 2)
(defparameter *test3* *test*) ; a new copy
(setf *test* (cons 3 *test*)) ; *test* is (3 2), but *test2* is still (1 2) and *test3* is still (2)

pushpop为你做这件事。这是相同的代码:

(defparameter *test* '(1 2))
(defparameter *test2* *test*) ; a copy
(pop *test*)                  ; *test* is (2), but *test2* is still (1 2)
(defparameter *test3* *test*) ; a new copy
(push 3 *test*)               ; (3 2), but *test2* is still (1 2) and *test3* is still (2)

我在这里不做的是(setf (car *test*) 3)因为它会改变对象并且所有引用都将获得相同的对象,因为它们指向我更改的对象。

所以如果你有某种更复杂的状态,比如哈希表,你需要把它变成一棵树,这样你就可以在每次更新时更改 log(n) 个节点,它会以同样的方式工作,那个旧的引用仍然具有相同的状态。

于 2018-11-05T22:30:32.960 回答