1

連想リストのエントリの変更に問題があります。このコードを実行すると

例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?

Dict2 番目のケースで が更新されないのはなぜですか?

編集

私が望むのは、エントリがにあるかどうかを確認し、ある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

2 に答える 2

4

letn式では、変数entryに参照ではなく関連付けのコピーが含まれています。Cormullion の例に示すように、関連付けを直接設定します。

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

newLISP プログラミング モデルでは、すべてを 1 回だけ参照できます。割り当ては常にコピーを作成します。

于 2012-11-15T14:04:04.487 に答える
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"))))
于 2012-11-15T13:20:06.910 に答える