2

我见过这个用过一次,但不明白它的作用。参考说它是

#n=object读作任何以 object 作为其打印表示的对象。但是,该对象由 n 标记,n 是必需的无符号十进制整数,以便通过语法 #n# 进行可能的引用。标签的范围是被最外层的 read 调用读取的表达式;在这个表达式中,同一个标签可能不会出现两次。

对我来说,这只是 56 个随机选择的英语单词……你能举个例子说明什么时候可以使用它吗?

4

1 回答 1

7

在 Common Lisp 中,它被阅读器和打印机使用。

这样,您可以在某个 s 表达式中标记一个对象,并在 s 表达式中的不同位置引用它。

标签#someinteger=后跟一个 s 表达式。整数必须是唯一的。您不能在单个 s 表达式中使用该标签两次。

对标签的引用是#someinteger#。整数标识要引用的 s 表达式。必须先引入标签,然后才能引用它。引用可以在 s 表达式中多次使用。

例如,这用于读取和打印具有共享数据对象的循环列表或数据结构。

这是一个简单的例子

? '(#1=(1 . 2) (#1#))

读作

((1 . 2) ((1 . 2)))

还要注意这一点:

? (eq (first *) (first (second *)))
T

这是一个相同的缺点单元。

让我们尝试一个循环列表

确保打印机处理循环列表并且不会永远打印它们......

? (setf *print-circle* t)
T

现在我们正在构建一个列表:

? (setf l1 (list 1 2 3))
(1 2 3)

我们将最后一个 cdr 设置为第一个缺点:

? (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 对象的引用。

于 2012-09-29T02:07:08.150 回答