5

以下のコードzはローカル変数として持っていますが、グローバルであるかのように動作します。

(defun foo (m)
  (let ((z '(stuff nil)))
    (push m (getf z 'stuff))
    (print z)))

(foo 1)
(foo 2)
(foo 3)

出力は次のようになると思います

(STUFF (1)) 
(STUFF (2)) 
(STUFF (3)) 
T

しかし、SBCLで実行すると、

(STUFF (1)) 
(STUFF (2 1)) 
(STUFF (3 2 1)) 
T

なぜそうなのですか?この動作はプロパティリストに特有のものですか?

4

1 に答える 1

6

ではfoozリテラル式 にバインドされています'(stuff nil)。この関数zは を破壊的に変更し、リテラルの値を破壊的に変更します。このような状況で LISP がどのように動作するかは、実装に依存します。一部の実装では、リテラル値を素直に変更します(あなたの場合のように)。他の実装では、リテラルを読み取り専用のメモリ ロケーションに配置し、それらのリテラルを変更しようとすると失敗します。

目的の動作を得るには、COPY-LIST安全に変更できるリテラルのコピーを作成するために使用します。

(defun foo (m)
  (let ((z (copy-list '(stuff nil))))
    (push m (getf z 'stuff))
    (print z)))
于 2011-01-08T05:39:01.623 に答える