突变,虽然允许,但在 Scheme 中强烈反对。PLT 甚至删除了set-car!
and set-cdr!
(尽管他们用set-mcar!
and替换了它们set-mcdr!
)。然而,一个规范append!
出现在SRFI-1中。这append!
和你的有点不同。在 SRFI 中,实现可以但不需要修改 cons 单元以附加列表。
如果你想要一个append!
保证改变被附加到的列表的结构,你可能必须自己编写它。这并不难:
(define (my-append! a b)
(if (null? (cdr a))
(set-cdr! a b)
(my-append! (cdr a) b)))
为了使定义简单,这里没有错误检查,但很明显,您需要传入长度至少为 1 的列表 asa
和(最好)一个(任意长度的)列表 as b
。原因a
必须至少为长度 1 是因为您不能set-cdr!
在空列表中。
既然你对它的工作原理感兴趣,我会看看我是否能解释一下。基本上,我们想要做的是沿着列表向下a
直到我们到达最后cons
一对,即(<last element> . null)
. 所以我们首先a
通过null
在cdr
. 如果是,我们将set-cdr!
其设置为我们要附加的列表,我们就完成了。如果没有,我们必须my-append!
调用cdr
of a
。每次我们这样做时,我们都会接近a
. 由于这是一个变异操作,我们不会返回任何东西,所以我们不需要担心将修改后的列表形成为返回值。