2.6 循环对象的读取语法

要在一组 Lisp 对象中表示共享或循环结构,你可以使用读取器构造符 ‘#n=’ 和 ‘#n#’。

在一个对象前使用 #n= 可为其添加标签,以便后续引用;之后,你可以在其他位置使用 #n# 来引用同一个对象。其中 n 是某个整数。例如,以下写法可创建一个列表,使其第一个元素同时作为第三个元素出现:

(#1=(a) b #1#)

这与如下普通语法不同:

((a) b (a))

后者生成的列表中,第一个和第三个元素看起来相同,但并非同一个 Lisp 对象。以下代码可体现这种差异:

(prog1 nil
  (setq x '(#1=(a) b #1#)))
(eq (nth 0 x) (nth 2 x))
     ⇒ t
(setq x '((a) b (a)))
(eq (nth 0 x) (nth 2 x))
     ⇒ nil

你也可以使用相同的语法创建循环结构(即对象自身包含自身作为元素)。示例如下:

#1=(a #1#)

这会创建一个列表,其第二个元素就是该列表本身。可通过以下方式验证其效果:

(prog1 nil
  (setq x '#1=(a #1#)))
(eq x (cadr x))
     ⇒ t

若将变量 print-circle 绑定为非-nil 值,Lisp 打印器会生成此类语法,以记录 Lisp 对象中的循环和共享结构。See 影响输出的变量

emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike