我对Scheme中的破坏性操作感到困惑。假设我有一个列表和一些在全球环境中定义的破坏性程序:
(define a '(a b c))
(define (mutate-obj x)
(set! x '(mutated)))
(define (mutate-car! x)
(set-car! x 'mutated))
(define (mutate-cdr! x)
(set-cdr! x 'mutated))
然后我们有以下表达式评价:
(mutate-obj! a) a => (a b c)
(mutate-car! a) a => (mutated b c)
(mutate-cdr! a) a => (mutated . mutated)
当set!
和a
都有set-car!
时,为什么set-cdr!
不会对(mutated)
的程序产生影响?为什么第一行的表达式不能评估为{{1}}?所有这些都真的有用吗?
答案 0 :(得分:0)
第一个例子没有像你想象的那样工作。虽然x
参数和a
全局变量都指向同一个列表,但是当您执行(set! x '(mutated))
时,只需将x
(过程的本地参数)设置为指向不同的列表,a
保持不变。如果你这样写,那就不一样了:
(define (mutate-obj)
(set! a '(mutated)))
现在a
在程序中变异了。第二个和第三个过程正在修改a
列表的内容,也由x
指向,因此一旦过程返回,更改就会反映在“外部”。