2012-11-15 80 views
1

修改關聯列表的條目時遇到問題。當運行此代碼newLISP:修改關聯列表

實施例A

(set 'Dict '(("foo" "bar"))) 

(letn (key "foo" 
     entry (assoc key Dict)) 
    (setf (assoc key Dict) (list key "new value"))) 

(println Dict) 

結果是:

(("foo" "new value")) ; OK 

預計。與此代碼

實施例B

(set 'Dict '(("foo" "bar"))) 

(letn (key "foo" 
     entry (assoc key Dict)) 
    (setf entry (list key "new value"))) ; the only change is here 

(println Dict) 

結果是:

(("foo" "bar")) ; huh? 

爲什麼Dict沒有被在第二種情況下更新?

編輯

我想是檢查條目是否是在Dict,如果它是 - 更新,否則不要管它。隨着letn我想避免重複碼

(letn (key "foo" 
     entry (assoc key Dict)) 
    (if entry ; update only if the entry is there 
    (setf entry (list key "new value"))) 

回答

4

letn表達變量ENT ry包含該協會的副本而不是參考。如Cormullion示例中所示直接設置關聯:

(setf (assoc key Dict) (list key "new value")) 

在newLISP編程模型中,一切只能引用一次。作業總是做一個副本。

+0

這就是我在例A中所做的......我想要做的就是檢查一個條目是否在'Dict'中,如果是 - 修改它。用'letn'我想避免重複的代碼 –

2

我協會的理解列出的是,他們的工作是這樣的:

> (set 'data '((apples 123) (bananas 123 45) (pears 7))) 
((apples 123) (bananas 123 45) (pears 7)) 
> (assoc 'pears data) 
(pears 7) 
> (setf (assoc 'pears data) '(pears 8)) 
(pears 8) 
> data 
((apples 123) (bananas 123 45) (pears 8)) 
> (assoc 'pears data) 
(pears 8) 
> 

如果您要檢查鑰匙的存在和更新其價值,做這樣的事情:

(letn (key "foo") 
    (if (lookup key Dict) 
     (setf (assoc key Dict) (list key "new value"))))