我在使用Scheme和列表的一个项目中注意到了这种半怪异的行为.我设法将行为隔离到一个部分.代码是:
(define x (list 1 2 3))
(define y (list 4 5))
(define z (cons (car x) (cdr y)))
(define w (append y z))
(define v (cons (cdr x) (cdr y)))
(set-car! x 6)
(set-car! y 7)
(set-cdr! (cdr x) (list 8))
x
y
z
w
v
Run Code Online (Sandbox Code Playgroud)
给我们的输出:
(6 2 8)
(7 5)
(1 5)
(4 5 1 5)
((2 8) 5)
Run Code Online (Sandbox Code Playgroud)
任何人都可以向我解释:
(set-car! x 6)更新Z?因为根据我的理解car/ cdr返回指针或引用相应的值.这真的很奇怪,我有点困惑.car/ cdr不返回引用/指针,那么最终如何set-cdr!操作列表v?有任何想法吗?这是一个简单的修复,但我更好奇为什么变量的奇怪性正在发生.
Chr*_*ung 22
好的,让我们逐行完成你的程序.我也为每个新创建的对象分配唯一的数字(将它们视为对象地址,如果你习惯使用类C语言),这样你就可以看到它是什么了.:-)
(define x (list 1 2 3)) ; => #1 = (1 . #2), #2 = (2 . #3), #3 = (3 . ())
(define y (list 4 5)) ; => #4 = (4 . #5), #5 = (5 . ())
(define z (cons (car x) (cdr y))) ; => #6 = (1 . #5)
(define w (append y z)) ; => #7 = (4 . #8), #8 = (5 . #6)
(define v (cons (cdr x) (cdr y))) ; => #9 = (#2 . #5)
(set-car! x 6) ; => #1 = (6 . #2)
(set-car! y 7) ; => #4 = (7 . #5)
(set-cdr! (cdr x) (list 8)) ; => #2 = (2 . #10), #10 = (8 . ())
Run Code Online (Sandbox Code Playgroud)
现在,让我们看看你的值(对于每个引用,使用最后指定的值):
x ; #1 => (6 . #2) => (6 . (2 . #10)) => (6 2 8)
y ; #4 => (7 . #5) => (7 5)
z ; #6 => (1 . #5) => (1 5)
w ; #7 => (4 . #8) => (4 . (5 . #6)) => (4 . (5 . (1 . #5))) => (4 5 1 5)
v ; #9 => (#2 . #5) => ((2 . #10) 5) => ((2 8) 5)
Run Code Online (Sandbox Code Playgroud)
编辑:我正在添加一个图表来解释我的答案,因为你不能在评论中有图表.我没有时间制作显示上述值的图表,但这有希望解释一些事情.

每对有两个"槽",car以及cdr,表示如上述图中的左和右框.如您所见,每个插槽都有三个可能的东西:
let,s5和sqrt)您可以将其中任何一个放入任何插槽中.因此,在我上面的解释中,每个#项目都是箭头,每个非#数字都是一个原子,每个()都是一个黑盒子.所以,在线
(define v (cons (cdr x) (cdr y)))
Run Code Online (Sandbox Code Playgroud)
你正在创建一对,其中左侧插槽的内容与右侧插槽的内容相同x(即箭头转到第2对),右侧插槽的内容与右侧插槽的内容相同的y(箭头要配对5).换句话说,两个框都v包含箭头,每个箭头都有一对不同的箭头.
希望这更有意义.:-)