获取指向Emacs Lisp中的列表元素的指针

时间:2013-02-05 12:08:47

标签: lisp elisp

例如,我有一个列表:

(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中是否可行?

2 个答案:

答案 0 :(得分:8)

通常,您无法存储对象的“地址”。但是,您可以参考cons单元格(cons单元格是由哪些列表组成)。稍后可以使用setcarsetcdr修改cons单元格。

例如:

(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那样打破了函数式编程范例......

答案 1 :(得分:4)

你可以做到

(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)