例如,我有一个列表:
(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中是否可行?
答案 0 :(得分:8)
通常,您无法存储对象的“地址”。但是,您可以参考cons单元格(cons单元格是由哪些列表组成)。稍后可以使用setcar
和setcdr
修改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-ref
和gv-deref
,在这种情况下可以正常工作。它们的工作方式与C &
和*
:
(setq pointer (gv-ref (nth 3 foo)))
...
(setf (gv-deref pointer) 444)