未经加工的符号主要用作名称或标识符,以避免包中出现混乱或用于相关任务。
例如:
T1> (find-symbol "T2")
NIL
NIL
T1> (find-symbol "T3")
NIL
NIL
T1> (defpackage t2)
#<Package "T2">
T1> (defpackage #:t3)
#<Package "T3">
T1> (find-symbol "T2")
T2
:INTERNAL
T1> (find-symbol "T3")
NIL
NIL
正如您所看到的,在第一个
defpackage
表单中使用
t2
会将其放置在
t1
包中,而在第二个
defpackage
中使用
#:t3
则避免了这种情况。这是可能的,因为
defpackage
接受一个字符串设计者作为其第一个元素,而符号不需要被interned以作为设计者。
这些和相关情况是非interned符号主要有意使用的地方。您也可以通过使用字符串或关键字来避免污染包,但在第一种情况下,可能会出现人们使用与默认readtable-case不同的问题,而在第二种情况下,您将污染关键字包,这对于一些人来说很重要。(对于这是否真的是一个坏事有不同的意见。)
然后,还有一些情况下,符号失去了它的home-package(例如通过
unintern
),并且至少变得明显地未interned。(它可能仍然被interned在另一个包中。)
T1> (defparameter *t2* (find-symbol "T2"))
*T2*
T1> (import *t2* "T3")
T
T1> (symbol-package *t2*)
#<Package "T1">
T1> (unintern *t2*)
T
T1> (find-symbol "T2")
NIL
NIL
T1> (symbol-package *t2*)
NIL
T1> *t2*
#:T2
T1> (find-symbol "T2" "T3")
#:T2
:INTERNAL
T1> (unintern *t2* "T3")
T
T1> (import *t2* "T3")
T
T1> *t2*
T3::T2
T1> (symbol-package *t2*)
#<Package "T3">
因此,对于“是否有一种方法可以使使用(make-symbol)创建的符号变为内部符号?”这个问题的答案是肯定的:
T1> (import (make-symbol "T4"))
T
T1> (find-symbol "T4")
T4
:INTERNAL
我可以为一个符号分配一个值而不将其intern吗?
是的,虽然您会失去它可以通过名称和包唯一标识的属性,但您仍然可以使用其值槽、plist等:
T1> (let ((symbol '#:t5))
(setf (symbol-value symbol) 1)
(setf (get symbol :foo) :bar)
(setf (symbol-function symbol) (lambda ()))
(values (symbol-value symbol)
(get symbol :foo)
(symbol-function symbol)))
1
:BAR
#<Anonymous Function #xC829036>
是否可以重命名一个符号(interned或uninterned)?
修改符号名称的后果是不确定的。
未interned符号还能做什么?
我真的认为它们在包定义中主要用作指示器,但一般的答案是:它们可以在您想要命名事物而不使用硬编码字符串和不想污染任何包的情况下非常有用。