2012-11-15 60 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"))))