scheme深拷贝和浅拷贝探索
> (define a '(1 2 3)) > (define b (cons a '())) > b ((1 2 3)) > (set-car! (car b) 100) > b ((100 2 3)) > a (100 2 3) >
从上面可以看到,(car b)和a是同一对象.
这个实在是有些危险啊.
如何让a和b能够相互独立呢?
下面这个函数返回的list各成员和最初传入的list各成员又是相互独立的:
;反序 (1 2 3) -> (3 2 1) (define (rvs x) (let recur ((x x)(res '())) (if (null? x) res (recur (cdr x) (cons (car x) res))))) (define x '(1 2 3 4)) (define a (rvs x)) (set-car! a 100) a x
结果:
(100 3 2 1)
(1 2 3 4)
我发现,同样是cons,例1是:
(cons a '()) ,而a引用的对象是列表'(1 2 3)
而例2是:
(cons (car x) res),(car x)引用的对象是数字
这说明,关键在于cons的参数是不是原子类型(atom).
如果是原子类型,那么就是深拷贝.否则就只是增加一个引用.
应该是这样了,下面这个例子很清楚的说明这个问题:
> (define a '(1 2 3)) > (define b (cons (car a) '())) ; (car a)是原子类型 > b (1) > (set-car! b 100) > b (100) > a ;所以(car a)和(car b)是相互独立的 (1 2 3) > (define b (cons (cdr a) '())) ;(cdr a)不是原子类型 > b ((2 3)) > (set-car! (car b) 100) > b ((100 3)) > a (1 100 3) ;所以(cdr a)和(car b)实际是同一对象 >