6

例如,我有一个列表:

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

然后我需要获得一个指向其第三个索引元素的指针(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

通常,您不能存储对象的“地址”。但是,您可以参考 cons 单元格(cons 单元格是列表的组成部分)。稍后可以使用setcarand修改 cons 单元格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)

那是行不通的。在我最近添加的 Emacs 的主干gv-refgv-deref,在这种情况下它可以正常工作。它们的工作方式与 C 非常相似&,并且*

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