2

我正在关注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 值?是什么让第一种形式如此特别以至于返回的值不会是字符串?

4

1 回答 1

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 手册包含更多关于文本属性的信息。

于 2012-09-11T20:21:22.720 回答