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

Ale*_*sky 6 lisp elisp

例如,我有一个列表:

(setq foo '(1 2 3 4 5))
Run Code Online (Sandbox Code Playgroud)

然后我需要获得一个指向其第三个索引元素的指针(4在示例中包含):

(setq p (SOME_FUNCTION foo 3))
Run Code Online (Sandbox Code Playgroud)

具有p地址的元素可以移动到另一个列表,因此我不能只保存其当前foo的索引.

我需要稍后再说:

(push 0 foo)
=> (0 1 2 3 4 5)
(setf p 444)
Run Code Online (Sandbox Code Playgroud)

并且列表foo必须在(0 1 2 3 444 5)之后.

这在Emacs lisp中是否可行?

Lin*_*cer 8

通常,您不能存储对象的"地址".但是,您可以参考cons单元格(cons单元格是由哪些列表组成).稍后可以使用setcar和修改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)
Run Code Online (Sandbox Code Playgroud)

在这里,foo有价值(0 1 2 3 444 5).

请注意,这实际上并不像lisp那样,打破了函数式编程范式......


Ste*_*fan 5

你可以做

(setq p (nth 3 foo))
Run Code Online (Sandbox Code Playgroud)

并将其存储在p存储在您想要的索引处的值中。你也可以这样做

(setf (nth 3 foo) 444)
Run Code Online (Sandbox Code Playgroud)

在那个地方存储 444。但是如果你尝试做类似的事情

(setq pointer (nth 3 foo))
...
(setf pointer 444)
Run Code Online (Sandbox Code Playgroud)

那行不通。在Emacs的后备箱我最近增加gv-ref以及gv-deref其将工作在这种情况下就好了。它们的工作方式非常类似于 C&*

(setq pointer (gv-ref (nth 3 foo)))
...
(setf (gv-deref pointer) 444)
Run Code Online (Sandbox Code Playgroud)