我正在关注elisp的介绍。第一章。这是我从html书中复制/粘贴的两个例子。我已经评估了两种形式,在这里我复制/粘贴返回的值和输出作为* Messages *缓冲区的副作用(我不知道如何复制迷你缓冲区内容)。
第一种形式
(let ((zebra 'stripes)
(tiger 'fierce))
(message "One kind of animal has %s and another is %s."
zebra tiger))
来自* Messages *
的输出One kind of animal has stripes and another is fierce.
#("One kind of animal has stripes and another is fierce." 23 30 (fontified t))
第二种形式
(let ((birch 3)
pine
fir
(oak 'some))
(message "Here are %d variables with %s, %s and %s value."
birch pine fir oak))
来自* Messages *的输出是:
Here are 3 variables with nil, nil and some value.
"Here are 3 variables with nil, nil and some value."
为什么第一个表格会返回一个lambda值? 是什么让第一个表单如此特殊以至于返回的值不是字符串?
答案 0 :(得分:10)
message
返回类型只是一个字符串。在*Messages*
缓冲区中,您可以看到message
的返回值(由评估命令在回显区域中显示在引号中),以及由message
本身在回显区域中显示的未加引号的字符串。第一个结果不是lambda,而是带有文本属性的字符串。
在Emacs中,字符串对象的可打印表示通常是双引号中的内容,如第二个示例中所示。但是,附加了文本属性的字符串将以更复杂的方式打印,如#("...string contents..." start end (property value...) ...)
。这种扩展语法是Lisp阅读器能够在从文本表示中读回字符串时重新创建属性。您可以通过在新缓冲区中评估M-: (insert #("foo" 0 3 (face (:foreground "yellow"))))
来测试这一点 - 文本将显示为黄色,因为字符串本身包含将其绘制为黄色的说明。 (要看到这一点,你需要处于一个新的缓冲区中,比如C-x b randomname RET
- 它不会在*scratch*
这样的语法高亮缓冲区中起作用,因为它们会自己着色文本。)
因此,您打印的第一个字符串附带了属性,可能是复制和粘贴的工件,这就是为什么它打印为#("..." ...)
。第二个字符串没有属性,可以打印成简单的字符串。
Emacs Lisp manual包含有关文字属性的更多信息。