在lisp中引用符号的确切含义是什么?

时间:2011-02-22 02:53:30

标签: emacs elisp common-lisp

(message "%s" 'abc)
(message "%s" "abc")

我发现前两个表达式都是相同的结果(在emacs中)。 虽然我知道这不是一个显示我问题的属性示例。

你能解释一下引用符号的确切含义吗? 引用的符号会返回什么?变量名称或其他内容的字符串表示形式?

5 个答案:

答案 0 :(得分:5)

最简单的答案是:符号在系统中是唯一的,而字符串则不是。 以下测试将明确指出:

? (eq 'abc 'abc) 
T 
? (eq "abc" "abc")
NIL

符号在系统中仅实习一次。所有进一步的参考都指向同一个对象。换句话说,符号是单例,比较两个符号只是比较指针的问题。所以它更快。字符串不是这种情况。在上面的示例中,字符串"abc"的两个实例是两个对象。

答案 1 :(得分:3)

Lisp中的符号有多种用途,包括但不限于:

  • 一种简单的数据类型,用于表示其他简单数据类型不能或不应该存在的任何原子 - 因此类似于C系列语言中的枚举。例如,函数MakeWidget可以采用参数Size,其可能的值为“small”,“medium”和“large”。不需要声明以这种方式使用的符号,但是如果需要,可以使用简单的方法来限制值的范围。
  • 变量名称
  • 功能名称

带引号的符号返回符号本身。

可以打印符号,并且如您所见,打印就像一个字符串。

那么,为什么要在使用字符串时使用符号呢?

  • 符号的名称不会更改,因此它使用的内存少于字符串
  • 符号可用于存储对要以非平凡方式调用的函数的引用。典型的例子是将函数应用于列表 - 例如,如果square是正确定义的函数,则:

(apply #'square '(1 2 3 4))

返回

(1 4 9 16)

此处未提及的符号还有其他用途,但希望这会给你一个良好的开端。

答案 2 :(得分:2)

报价只会关闭您引用的表单上的评估。确切地说,这会改变,具体取决于你使用的是什么,以及你引用的内容。

评估符号通常涉及查找该符号的值。引用符号将关闭该查找,这意味着返回符号本身。打印符号会打印符号的名称,这就是您从两个示例中获得相同输出的原因。

答案 3 :(得分:1)

带引号的符号计算符号本身。

符号有一个名称(可能还有其他类似值)。如果您打印符号,则会打印其名称。

答案 4 :(得分:1)

添加到上面的内容:

字符串和符号都可以是“唯一的”(上面说的不正确)。它们是具有身份的物体。

(setq foo "abc")

(setq bar foo)

(eq foo bar)

变量foobar的值是相同的(唯一)字符串。

(eq "abc" "abc")是非nil的原因是Lisp阅读器从这两个文字字符串表达式生成两个不同的字符串对象。另一方面,当Lisp阅读器遇到abc时,它会将其读作符号名称。它(正如上面所说的那样)第一次使用该名称实习符号,然后查看符号名称。

Wrt评估:

  • 字符串是自引用的;也就是说,他们评价自己。大多数符号不是(tnil是值得注意的例外情况。)

  • 在评估期间,查找符号以获得(a)其关联函数,如果它在上下文中用作函数或(b)其关联值,如果它在上下文中用作变量

(abc xyz)

  • 符号abc在上下文中用作函数,因此查找并使用其函数(函数“cell”的值)。

  • 符号xyz在上下文中用作变量,因此查找并使用其变量值(其变量“cell”的值)。

IOW,Emacs Lisp中的符号有两个“单元格”或含义:(a)作为函数,(b)作为变量。给定的符号可能未定义为变量或函数,或者它可能具有两种定义。

最后,根据您的意思,说(message "%s" "abc")(message "%s" 'abc)具有相同的价值是错误陈述。它们都返回相同的,即nil,并且它们都具有相同的效果,即打印abc