例如,我有一个列表:
(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中是否可行?
通常,您不能存储对象的"地址".但是,您可以参考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那样,打破了函数式编程范式......
你可以做
(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)
| 归档时间: |
|
| 查看次数: |
789 次 |
| 最近记录: |