Scheme 请求解释set car的意外行为!并在方案中定义

Scheme 请求解释set car的意外行为!并在方案中定义,scheme,lisp,Scheme,Lisp,在学习官方文件中的scheme命令时 这里发生了什么: > (define ls1 '((ignored) ignored)) #<unspecified> > ls1 ((ignored) ignored) > (set-car! (cdr ls1) 'a) #<unspecified> > ls1 ((ignored) a) 假设你有 (define end1 (cons 'ignored '())) (define ls1 (cons en

在学习官方文件中的scheme命令时

这里发生了什么:

> (define ls1 '((ignored) ignored))
#<unspecified>
> ls1
((ignored) ignored)
> (set-car! (cdr ls1) 'a)
#<unspecified>
> ls1
((ignored) a)
假设你有

(define end1 (cons 'ignored '()))
(define ls1 (cons end1 (cons 'ignored '())))
(define end2 (cons 'ignored '()))
(define ls2 (cons end2 end2))
显而易见,
ls2
指的是名为
end2
的同一实体,包括
car
cdr

完全不同的是,
ls1
的两个部分分别指不同的实体,
car
指的是
end1
cdr
,指的是另一次调用相同
cons
表单的结果:

(eq? end2 end2) ;=> #t
(eq? (car ls2) (cdr ls2)) ;=> #t
(eq? (car ls1) (cdr ls1)) ;=> #f
(equal? (car ls1) (cdr ls1)) ;=> #t
返回的
#t
表示这两个参数实际上是内存中的同一对象。因此,当您更改内存驻留对象的内容时,您也会更改内存驻留对象的内容。对于
ls2
,只涉及一个位置,即
end2
所指的位置:

(eq? (cdr ls2) end2)       ;=> #t
(set-car! (cdr ls2) 'a)    ; changes `end2` to '(a)
否则,每次新调用
cons
都保证在内存中创建并返回一个新位置,即使保持
equal?
内容。因此,更改一个副本不会影响位于内存中另一个位置的另一个副本:

(eq? (cdr ls1) end1)       ;=> #f
(set-car! (cdr ls1) 'a)    ; `end1` is unchanged
(eq? (cdr ls1) end1)       ;=> #f
(set-car! (cdr ls1) 'a)    ; `end1` is unchanged