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)实际是同一对象
> 
原文地址:https://www.cnblogs.com/xiangnan/p/3392423.html