我需要标准 CL 包符号名称(包括 NIL 和 T 的符号名称)在另一个包中为小写。
我发现明显需要的字符数量增加了在 Stackoverflow 上发布问题的解决方案,尽管仅将 DEFMACRO 用于函数是完全可以理解的。
我需要标准 CL 包符号名称(包括 NIL 和 T 的符号名称)在另一个包中为小写。
为此,您需要在不同的包中创建具有相同名称但小写名称的new符号。
符号内部只有一个名称,并且该符号是同一个对象,可以从不同的包访问。
如果您希望符号的内部名称具有不同的大小写,那么您需要创建一个新符号。
您不能这样做:符号的名称是符号的属性,因此符号
nil
的名称是 "NIL"
并且您无法更改它(尤其是对于 nil
!)。符号也只有一个名称。
要问的问题是,正如评论中提到的:您是否需要符号名称实际上be小写,或者您只是希望能够以小写形式输入并以小写形式打印?几乎总是后者就足够了,您可以通过控制两个参数来做到这一点。
*print-case*
控制打印机如何打印符号名称。如果您将其设置为:downcase
,那么当可以明确打印时,它们将以小写形式打印。
Readtables 控制阅读器,然后有一个由访问器控制的属性
readtable-case
控制它们的行为。这有几个选项,但默认的可读表是 :upcase
,它将自动使以小写形式输入的符号名称被保留为大写符号,这通常是您想要的。
这两个参数以相当复杂的方式相互作用,以确保打印的内容可读。 此处为读者进行了描述,此处为打印机进行了描述。
所有这一切的结果是,如果您将
*print-case*
设置为 :downcase
并且不更改其他任何内容,则该语言在大多数情况下都会表现得就像符号具有小写名称一样,但当您实际需要编写时除外解释符号名称的代码。
特别是:
> *print-case*
:downcase
> nil
nil
> (symbol-name 'nil)
"NIL"
> (eq 'nil 'NIL)
t
> (eq 'foo 'FOO)
t
> (symbol-name 'foo)
"FOO"
在实践中这会带来伤害,当你需要处理来自认为
NamesLikeThis
比 names-like-this
更好的语言的名称时。最好的方法可能是编写函数将一种约定转换为另一种约定,但除此之外,它只会有点痛苦。
至少有一种“不可移植”的方法来处理这个问题,那就是允许符号有“昵称”。它的作者将其描述为“一个坏掉的玩具”,事实就是如此。它可以在here找到,并且适用于多种实现。其示例之一是创建一个包,其中包含所有标准 CL 符号的小写昵称。然而,这实际上并不能解决大部分问题,因为查找昵称会返回其昵称所在的符号。我建议不要使用这个系统,因为它很脆弱且不可移植。