在 Common Lisp 中,它由阅读器和打印机使用。
通过这种方式,您可以在某些 s 表达式中标记对象,并在 s 表达式中的不同位置引用它。
标签是#someinteger=
后跟一个 s 表达式。该整数必须是唯一的。您不能在单个 s 表达式中使用该标签两次。
对标签的引用是#someinteger#
。该整数标识要引用的 s 表达式。必须先引入标签,然后才能引用它。该引用可以在 s 表达式中多次使用。
例如,这用于读取和打印具有共享数据对象的循环列表或数据结构。
这是一个简单的例子:
? '(#1=(1 . 2) (#1#))
reads as
((1 . 2) ((1 . 2)))
还要注意这一点:
? (eq (first *) (first (second *)))
T
这是一个相同的缺点单元格。
让我们尝试一下循环列表.
确保打印机处理循环列表并且不会永远打印它们......
? (setf *print-circle* t)
T
现在我们正在构建一个列表:
? (setf l1 (list 1 2 3))
(1 2 3)
我们将最后一个 cdr 设置为第一个 cons:
? (setf (cdr (last l1)) l1)
#1=(1 2 3 . #1#)
正如您在上面看到的,打印的列表有一个标签,最后一个 cdr 是对该标签的引用。
我们也可以使用相同的符号直接输入循环列表。读者这样理解:
? '#1=(1 2 3 . #1#)
#1=(1 2 3 . #1#)
由于我们已经告诉打印机处理此类结构,因此我们可以尝试第一个示例中的表达式:
? '(#1=(1 . 2) (#1#))
(#1=(1 . 2) (#1#))
现在打印机检测到有两个对同一个 cons 对象的引用。