第八章:符号

2018-02-24 15:50 更新

我们一直在使用符号。符号,在看似简单的表面之下,又好像没有那么简单。起初最好不要纠结于背后的实现机制。可以把符号当成数据对象与名字那样使用,而不需要理解两者是如何关联起来的。但到了某个时间点,停下来思考背后是究竟是如何工作会是很有用的。本章解释了背后实现的细节。

8.1 符号名 (Symbol Names)

第二章描述过,符号是变量的名字,符号本身以对象所存在。但 Lisp 符号的可能性,要比在多数语言仅允许作为变量名来得广泛许多。实际上,符号可以用任何字符串当作名字。可以通过调用 symbol-name 来获得符号的名字:

> (symbol-name 'abc)
"ABC"

注意到这个符号的名字,打印出来都是大写字母。缺省情况下, Common Lisp 在读入时,会把符号名字所有的英文字母都转成大写。代表 Common Lisp 缺省是不分大小写的:

> (eql 'abc 'Abc)
T
> (CaR '(a b c))
A

一个名字包含空白,或其它可能被读取器认为是重要的字符的符号,要用特殊的语法来引用。任何存在垂直杠 (vertical bar)之间的字符序列将被视为符号。可以如下这般在符号的名字中,放入任何字符:

> (list '|Lisp 1.5| '|| '|abc| '|ABC|)
(|Lisp 1.5| || |abc| ABC)

当这种符号被读入时,不会有大小写转换,而宏字符与其他的字符被视为一般字符。

那什么样的符号不需要使用垂直杠来参照呢?基本上任何不是数字,或不包含读取器视为重要的字符的符号。一个快速找出你是否可以不用垂直杠来引用符号的方法,是看看 Lisp 如何印出它的。如果 Lisp 没有用垂直杠表示一个符号,如上述列表的最后一个,那么你也可以不用垂直杠。

记得,垂直杠是一种表示符号的特殊语法。它们不是符号的名字之一:

> (symbol-name '|a b c|)
"a b c"

(如果想要在符号名称内使用垂直杠,可以放一个反斜线在垂直杠的前面。)

译注: 反斜线是 \ (backslash)。

8.2 属性列表 (Property Lists)

在 Common Lisp 里,每个符号都有一个属性列表(property-list)或称为 plist 。函数 get 接受符号及任何类型的键值,然后返回在符号的属性列表中,与键值相关的数值:

> (get 'alizarin 'color)
NIL

它使用 eql 来比较各个键。若某个特定的属性没有找到时, get 返回 nil 。

要将值与键关联起来时,你可以使用 setf 及 get :

> (setf (get 'alizarin 'color) 'red)
RED
> (get 'alizarin 'color)
RED

现在符号 alizarin 的 color 属性是 red 。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号