2014-10-06 37 views
1

我一直在試圖修改一個哈希表,下面的代碼修改哈希表中的Common Lisp和讓

(let ((alist '(gethash key *hash-table*))) 
    (setf alist (cons 'key 'weight))) 

但問題是,它實際上並沒有改變哈希表(還要注意

(let ((alist (gethash key *hash-table*))) 
    (setf alist (cons 'key 'weight))) 

也不管用,而下面的代碼做的工作。

(setf (gethash key *hash-table*) (cons 'key 'weight))) 

我不明白爲什麼這有效,另一個不起作用。這是有用的(超出此代碼段),因爲(我認爲)這就是爲什麼我不能運行像

(alist-initialize (gethash key *hash-table*)) 

與定義是一個功能:

(defun alist-initialize (alist) 
    (setf alist (cons 'a 'b)) 

回答

9

設置變量修改其本地綁定。 你不會想到

(let ((a 5)) 
    (setf a 2)) 

5值在某種程度上改變2。 同樣,

(let ((alist (gethash key *hash-table*))) 
    (setf alist (cons 'key 'weight))) 

(gethash key *hash-table*)沒有影響。 發生什麼事是key它擡頭在*hash-table*alist被綁定到返回的值。然後setf修改alist的綁定,完全無視先前的綁定。

(請注意,您的第一個引號引用了[gethash][2]調用,因此根本不訪問哈希表)。

你的功能應該被定義是這樣的:

(defun alist-initialize (key alist) 
    (setf (gethash key *hash-table*) alist)) 

,並呼籲與參數,不一個。 「爲了充分披露信息」,CL確實提供了你想要的設施(見symbol-macroletdefine-symbol-macro),但這是相對高級的材料,你現在應該IMO忽略它。

+0

改變以5比2確實的例子有用,謝謝。 – user124577 2014-10-06 02:59:43

1

爲什麼要混合關聯列表和散列表?兩者都可以用於類似的目的,但它們彼此獨立。

如果你想要把東西放到一個哈希表,你必須寫:

(setf (gethash key *hash-table*) value) 

如果你想要得到的值:

(gethash key *hash-table*)