我們一直在使用符號(hào)。符號(hào),在看似簡(jiǎn)單的表面之下,又好像沒(méi)有那么簡(jiǎn)單。起初最好不要糾結(jié)于背后的實(shí)現(xiàn)機(jī)制。可以把符號(hào)當(dāng)成數(shù)據(jù)對(duì)象與名字那樣使用,而不需要理解兩者是如何關(guān)聯(lián)起來(lái)的。但到了某個(gè)時(shí)間點(diǎn),停下來(lái)思考背后是究竟是如何工作會(huì)是很有用的。本章解釋了背后實(shí)現(xiàn)的細(xì)節(jié)。
第二章描述過(guò),符號(hào)是變量的名字,符號(hào)本身以對(duì)象所存在。但 Lisp 符號(hào)的可能性,要比在多數(shù)語(yǔ)言僅允許作為變量名來(lái)得廣泛許多。實(shí)際上,符號(hào)可以用任何字符串當(dāng)作名字??梢酝ㄟ^(guò)調(diào)用?symbol-name
?來(lái)獲得符號(hào)的名字:
> (symbol-name 'abc)
"ABC"
注意到這個(gè)符號(hào)的名字,打印出來(lái)都是大寫(xiě)字母。缺省情況下, Common Lisp 在讀入時(shí),會(huì)把符號(hào)名字所有的英文字母都轉(zhuǎn)成大寫(xiě)。代表 Common Lisp 缺省是不分大小寫(xiě)的:
> (eql 'abc 'Abc)
T
> (CaR '(a b c))
A
一個(gè)名字包含空白,或其它可能被讀取器認(rèn)為是重要的字符的符號(hào),要用特殊的語(yǔ)法來(lái)引用。任何存在垂直杠 (vertical bar)之間的字符序列將被視為符號(hào)??梢匀缦逻@般在符號(hào)的名字中,放入任何字符:
> (list '|Lisp 1.5| '|| '|abc| '|ABC|)
(|Lisp 1.5| || |abc| ABC)
當(dāng)這種符號(hào)被讀入時(shí),不會(huì)有大小寫(xiě)轉(zhuǎn)換,而宏字符與其他的字符被視為一般字符。
那什么樣的符號(hào)不需要使用垂直杠來(lái)參照呢?基本上任何不是數(shù)字,或不包含讀取器視為重要的字符的符號(hào)。一個(gè)快速找出你是否可以不用垂直杠來(lái)引用符號(hào)的方法,是看看 Lisp 如何印出它的。如果 Lisp 沒(méi)有用垂直杠表示一個(gè)符號(hào),如上述列表的最后一個(gè),那么你也可以不用垂直杠。
記得,垂直杠是一種表示符號(hào)的特殊語(yǔ)法。它們不是符號(hào)的名字之一:
> (symbol-name '|a b c|)
"a b c"
(如果想要在符號(hào)名稱內(nèi)使用垂直杠,可以放一個(gè)反斜線在垂直杠的前面。)
譯注: 反斜線是?\
?(backslash)。
在 Common Lisp 里,每個(gè)符號(hào)都有一個(gè)屬性列表(property-list)或稱為?plist
?。函數(shù)?get
?接受符號(hào)及任何類型的鍵值,然后返回在符號(hào)的屬性列表中,與鍵值相關(guān)的數(shù)值:
> (get 'alizarin 'color)
NIL
它使用?eql
?來(lái)比較各個(gè)鍵。若某個(gè)特定的屬性沒(méi)有找到時(shí),?get
?返回?nil
?。
要將值與鍵關(guān)聯(lián)起來(lái)時(shí),你可以使用?setf
?及?get
?:
> (setf (get 'alizarin 'color) 'red)
RED
> (get 'alizarin 'color)
RED
現(xiàn)在符號(hào)?alizarin
?的?color
?屬性是?red
?。
更多建議: