在LISP的一个功能语言系列中,有可能定义变量,
(defvar a '(1 2 3))
(defvar b (cons a (cdr a)))
(rplacd a '(5))
将b
列表创建为
((1 5) 2 3)
!!我很惊讶。这些代码片段如何列出此列表?任何人都可以解释这些令人困惑的命令吗?!
答案 0 :(得分:4)
执行前两个defvar
调用后,您将对conses进行以下变量赋值。
A => +---+---+ +---+---+ +---+---+
+--> | 1 | ---->| 2 ---->| 3 | ----> NIL
\ +---+---+ +---+---+ +---+---+
\ --^
\ /
\ /
\ /
\ /
B => +-\-+-|-+
| | | | |
+---+---+
在印刷表示中,这看起来像:
A => (1 2 3)
B => ((1 2 3) 2 3)
执行rplacd
时,它会修改cdr
的{{1}}以引用新的a
。但cons
的{{1}}仍然指的是与之前相同的cdr
。
b
以印刷形式,如下所示:
cons
理解Lisp赋值的重要一点是它们不会复制列表结构,它们只是分配对conses的引用(如果你熟悉像C这样的语言,就像所有东西都指向一个 +---+---+
->| 5 | ----> NIL
/ +---+---+
/
A => +---+-|-+ +---+---+ +---+---+
+--> | 1 | | | | 2 ---->| 3 | ----> NIL
\ +---+---+ +---+---+ +---+---+
\ --^
\ /
\ /
\ /
\ /
B => +-\-+-|-+
| | | | |
+---+---+
)。