21

Common Lisp 中的语法,变量前面的冒号是什么意思?我见过这样的程序,我将在这里展示一些示例代码,来自大量函数。

(defun expand (successorf node)
    (mapcar (lambda (action-state-cost)
          (let ((action (car action-state-cost))
                (state (cadr action-state-cost))
                (cost (caddr action-state-cost)))
            (make-node :state state :parent node
                       :action action :path-cost (+ (node-path-cost node) cost)
                       :depth (1+ (node-depth node)))
            ))
      (funcall successorf (node-state node))
      ))
4

2 回答 2

36

关键字符号

:foo关键字符号

  • KEYWORD在包中实习和导出
  • 不断地束缚于自己

用法

当需要以下属性的组合时使用关键字符号:

  • 符号是正确的数据结构
  • 具有相同名称的符号应该是唯一的(通过将它们放在一个包中)-> 包KEYWORD
  • 不需要或不需要不同的包 -> 包KEYWORD
  • 编写符号应该很容易,因为不需要引用它们 ->:foo':foo
  • 不需要充当具有不同值的变量的能力->对其自身:foo进行评估,:foo并且仅对:foo

在 Common Lisp 中,符号通常可以在一个包中(一种命名空间)。

bar包中未导出的符号foo写为foo::bar. 双冒号位于包名和符号名之间。

然后导出的符号写为foo:bar。使用单个冒号。

如果符号在当前包中可用,则写为bar没有包。

包裹KEYWORD

有一个特殊的包叫做KEYWORD. 该包中的符号bar简单且始终写为:bar.

例子

这些关键字符号也有这些有趣的属性:符号是自动从包中导出的KEYWORD(所以keyword::barkeyword:bar和都是同一个符号)并且它们对自己求值::bar:bar

CL-USER 5 > :bar
:BAR

CL-USER 6 > (describe :bar)

:BAR is a SYMBOL
NAME          "BAR"
VALUE         :BAR
FUNCTION      #<unbound function>
PLIST         NIL
PACKAGE       #<The KEYWORD package, 0/4 internal, 5830/8192 external>

CL-USER 7 > (eq 'keyword::bar ':bar)
T

CL-USER 8 > (eq :bar ':bar)  ; quoted or unquoted, each subform evaluates to :bar
T

用法

例如,关键字符号用作命名参数中的名称:

(defun foo (&key bar) (+ bar 10))

(foo :bar 7)

通常它们也用于实例和结构构造的参数。

(defstruct node state parent action)

DEFSTRUCT是一个 Common Lisp 宏,它生成几个函数。其中之一是一个函数MAKE-NODE,它可以用作:

(make-node :state 'open
           :parent some-parent
           :action an-action)

注意:有时数据也可能是关键字。例如在上面的形式中,状态可能是:open而不是open

(make-node :state :open
           :parent some-parent
           :action an-action)
于 2011-12-19T21:10:54.977 回答
21

实际上,它们不是变量。这些是关键字。它们是一种特殊的高效标记,类似于其他语言中的“原子”。这是一种方便的内置方式,可以将命名(并且几乎总是可选)参数传递给函数调用。

http://www.gigamonkeys.com/book/functions.html描述了函数调用的语法。

于 2011-12-19T20:46:29.350 回答