6

たとえば、次のリストがあります。

(setq foo '(1 2 3 4 5))

次に、3 番目のインデックス要素 (この4例では含まれています)へのポインターを取得する必要があります。

(setq p (SOME_FUNCTION foo 3))

p アドレスを持つ要素は別のリストに移動できるため、現在fooの のインデックスを保存することはできません。

そして、私は後で言うことができる必要があります:

(push 0 foo)
=> (0 1 2 3 4 5)
(setf p 444)

リストはその後でfooなければなりません。(0 1 2 3 444 5)

これは Emacs Lisp で可能ですか?

4

2 に答える 2

8

一般に、オブジェクトの「アドレス」を保存することはできません。ただし、コンス セルを参照することはできます (コンス セルはリストの構成要素です)。コンスセルは、後で and を使用して変更できsetcarますsetcdr

例えば:

(defvar my-cons-cell nil)

(defun my-save-cons-cell (cons-cell)
  (setq my-cons-cell cons-cell))

(defun my-set-car-in-saved-cons-cell (value)
  (setcar my-cons-cell value))

;; Test

(setq foo '(1 2 3 4 5))

(my-save-cons-cell (cdr (cdr (cdr foo))))

(push 0 foo)

(my-set-car-in-saved-cons-cell 444)

ここでfoo、値は です(0 1 2 3 444 5)

これは実際には Lisp に似ておらず、関数型プログラミングのパラダイムを壊していることに注意してください...

于 2013-02-05T12:22:51.797 に答える
5

できるよ

(setq p (nth 3 foo))

必要なインデックスに格納されpている値に格納されます。あなたもできる

(setf (nth 3 foo) 444)

その場所に444を格納します。しかし、次のようなことをしようとすると

(setq pointer (nth 3 foo))
...
(setf pointer 444)

それはうまくいきません。最近追加gv-refした Emacs のトランクでgv-derefは、このような場合に問題なく動作します。&それらは Cとほとんど同じように動作し*ます:

(setq pointer (gv-ref (nth 3 foo)))
...
(setf (gv-deref pointer) 444)
于 2013-02-05T13:22:03.087 に答える