考虑缺点x1
:
(setq x1 '(a . (b c))) => (a b c)
或以列表表示法:
(setq x1 '(a b c)) => (a b c)
和缺点x2
,建立在x1
:
(setq x2 (cons 'A (cdr x1))) => (A b c)
cons
help (在 Emacs 中)说该函数创建一个新的 cons,给它参数,'A
和(cdr x1)
, 作为组件并返回它。其中没有任何内容表明新返回的 cons 的生命周期将与其生成组件的生命周期相关联。
无论如何,如果有人修改了副本,x2
那么原始的缺点也会(a . (b c))
被修改:
(setcar (cdr x2) 'B) => B
x2 => (A B c) ; as from the assignment
x1 => (a B c) ; x1 and x2 are linked
其他函数示例可以显示 和 之间的x1
联系x2
。
(setq x1 '(a . (b c))) => (a b c)
(setq x2 (cons 'A (cdr x1))) => (A b c)
(nreverse x2) => (c b A)
x1 => (a b A)
我从 Emacs Lisp 参考手册中的文档中获取了这个示例setcar
,其中指出“cons 单元是共享结构的一部分”,并且 cdrx1
和x2
被称为“共享链接” x1
,x2
并且以图形方式显示为(稍微改编):
x1:
-------------- -------------- --------------
| car | cdr | | car | cdr | | car | cdr |
| a | o------->| b | o------->| c | nil |
| | | -->| | | | | |
-------------- | -------------- --------------
|
x2: |
-------------- |
| car | cdr | |
| A | o----
| | |
--------------
这让人想起 C 指针,因为 cdrx2
不是副本,而是“指向” 的 cdr x1
。很清楚,但我想知道这种情况何时实际出现,也就是说,我怎么知道一个 cons 的(一个元素)是指向另一个 cons 还是一个自活的副本?更一般地说,共享结构和共享链接 的正式定义是什么(在哪里)?
在 Emacs Lisp 参考手册中没有明确提及它们。事实上,在其索引中搜索“共享”或“链接”只会返回(不包括文件/网络链接)对“共享结构,读取语法”的间接引用,处理它们的表示,而不是它们是什么。
好奇地在 PDF 中搜索“共享”土地,作为第一次出现,到“读取圆形对象的语法”部分,从“表示共享或圆形结构......”开始。不幸的是,之前没有提到共享和循环(结构)这两个词!下一个事件是提到的setcar
文档。
所以在 Lisp/Elisp 中似乎有隐含的指针,但没有人愿意告诉他们。))