2011-12-19 29 views
14

Common Lisp中变量的语法,冒号是什么意思?我已经看过这样的程序,并且我将在这里展示一些示例代码,其中包含大量函数。为什么冒号在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)) 
    )) 

回答

18

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

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

27

关键字符号

:fookeyword符号

  • 实习中,并从KEYWORD
  • 不断结合到本身导出

用法

当需要以下性质的组合

关键字符号用于:

  • 符号是正确的数据结构
  • 符号具有相同的名称应该是唯一的(通过在一个包实习它们) - >包KEYWORD
  • 不同的包不需要或不想要的 - >包KEYWORD
  • 写符号应该很容易通过不需要引用它们 - >:foo':foo
  • 充当不需要用不同值的变量的能力,更好地 - >:foo计算结果为:foo本身只:foo

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

包中的未导出符号barfoo写为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) 
+0

你写的:“一个**输出符号** ......写为'富:bar' *一个冒号使用* ..“以及”[关键字]符号自动导出**“,但您的示例显示了'(eq'keyword :: bar':bar)'。如果关键字总是被导出,为什么你要用双冒号? ''''可以同时用于导出和非导出符号吗? – 2017-10-15 18:14:09

+0

@GlennSlayden是的,每个被导出或不导出的实体符号都可以写成package :: name。只有导出的符号可以写成package:name。只有关键字符号可以写为:name。 – 2017-10-15 18:19:09

+0

为了完整性,':: bar'怎么样?它是否仍然引用'KEYWORD'包,或者现在是否是其他形式的全局?很抱歉成为LISP新手。 – 2017-10-15 18:28:48