Scheme 请求解释set car的意外行为!并在方案中定义
在学习官方文件中的scheme命令时 这里发生了什么: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
> (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