(require racket/mpair)
(define (bld-mlst . args)
(list->mlist args))
(define mlst-my (bld-mlst))
mlst-my
(mappend! mlst-my (list->mlist (list 100)))
mlst-my
(define mlst-my2 (bld-mlst 2))
(mappend! mlst-my2 (list->mlist (list 100)))
mlst-my2
它会打印出来:
(mcons 100 '())
'()
(mcons 2 (mcons 100 '()))
(mcons 2 (mcons 100 '()))
第一行和第三行只是mappend的返回值!注意第二行和第四行!我们可以看到第二行是'()
,这意味着mappend!不会改变mlst-my
!当mlst-my2
不为空时,mappend!
工作正常。
的问题:
然后如何制作mappend!当mlist为空时,仍然会影响mlist?
答案 0 :(得分:3)
你不能!空列表是一个单例,不可变对象。它没有可以更改的插槽(汽车或cdr)。但你可以这样做:
(set! mlst-my (mappend! mlst-my (list->mlist (list 100))))
也就是说,您set!
变量为mappend!
的返回值。
要了解所有这些,请了解单个链接列表的工作原理。它包含 cons cells (或点对),每个都有两个插槽(传统上称为car
和cdr
)。 car
广告位指向该值,cdr
指向下一个消息/对。
因此,像(1 2 3)
这样的列表有三个结论:
#0=(1 . #1#)
#1=(2 . #2#)
#2=(3 . ())
append!
的工作方式是找到最后一个缺点(cdr
指向()
的那个),并将其cdr
更改为指向您的列表正在追加。
但是,如果您的列表为空,则它没有结果,因此无需更改。空列表总是不可变的。