儘管允許突變,但在Scheme中強烈建議不要使用突變。 PLT甚至刪除了set-car!
和set-cdr!
(儘管它們用set-mcar!
和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爲a
清單通過,並(最好)的列表(任何長度)爲b
。 a
必須至少爲1的原因是因爲您不能在空列表上登錄set-cdr!
。
既然你感興趣的是如何工作的,我會看看我能不能解釋一下。基本上,我們想要做的是沿着列表a
,直到我們到達最後cons
對,這是(<last element> . null)
。所以,我們先看看a
已經由cdr
爲null
檢查列表中的最後一個元素。如果是,我們使用set-cdr!
將其設置爲我們追加的列表,然後我們就完成了。如果不是,我們必須致電my-append!
,cdr
a
。每次我們這樣做,我們都會接近a
的結尾。由於這是一個變異操作,我們不會返回任何東西,所以我們不需要擔心將修改後的列表形成返回值。
後續問題 - 如果強烈建議忽略突變,那麼對於像「從嚮導對話框構建列表」這樣的模式,最佳做法是什麼? 從Ruby背景來看,這是我一直在努力理解..心態不僅僅是解決問題的實際代碼。 – 2009-07-03 18:15:35