Sharpsign等号读取器宏的示例?

时间:2012-09-29 01:53:52

标签: lisp common-lisp

我已经看过这个用过一次,但无法理解它做了什么。参考文献说它是

  

#n=object读取任何对象具有对象作为其打印表示。   但是,该对象标有n,是必需的   无符号十进制整数,可通过语法#n#进行参考。   标签的范围是最外层读取的表达式   打电话给;在此表达式中,可能不会出现相同的标签   两次。

对我来说,只读了56个随机选择的英语单词...请问您能举例说明何时可以使用这个单词?

1 个答案:

答案 0 :(得分:8)

在Common Lisp中,它由读者和打印机使用。

这样你可以在某个s-expression中标记一个对象,并在s-expression中的不同位置引用它。

标签为#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对象有两个引用。