如何将字符串转换为符号以用作Lisp"assoc"函数中的键?

זאב*_*כהן 2 lisp symbols common-lisp

我在Common Lisp中有这个关联列表:

(defvar base-list (list (cons 'a 0) (cons 2 'c)))
Run Code Online (Sandbox Code Playgroud)

assoc当我的论证属于类型时,我必须打电话string.

对于该对,(A . 0)我必须将"a"转换为符号,对于该对,(2 . C)我必须将"2"转换为符号.我怎样才能做到这一点?

这应该是这样的:

CL-USER 28 : 1 > (assoc (convert-string-to-symbol "a") base-list)
(A . 0)
CL-USER 28 : 1 > (assoc (convert-number-to-symbol "2") base-list)
(2 . C)
Run Code Online (Sandbox Code Playgroud)

我试过用intern但得到了NIL:

CL-USER 29 : 1 > (assoc (intern "a") base-list)
NIL
Run Code Online (Sandbox Code Playgroud)

小智 6

您想要的功能称为read-from-string:

CL-USER> (read-from-string "a")
A
1
CL-USER> (read-from-string "2")
2
1
CL-USER> 
Run Code Online (Sandbox Code Playgroud)

注意,在大多数实现中,基于使用internfind-symbol不适用于表示数字的字符串(例如,"2")的解决方案.


seh*_*seh 4

你与 很亲近intern;你只是把情况搞错了。尝试这个:

> (assoc (intern "A") base-list)
(A . 0)
Run Code Online (Sandbox Code Playgroud)

请注意,这里的名称字符串是大写的。

或者,您可以使用find-symbol按名称查找现有符号:

> (assoc (find-symbol "A") base-list)
(A . 0)
Run Code Online (Sandbox Code Playgroud)

这里的关键是,当您编写原始defvar形式时,读者会读取字符串“a”,并根据当前可读的大小写将符号名称转换为大写。名称大小写不同的符号不相等。碰巧的是,在阅读时,读者将您所写的内容(小写)投射到其他内容(大写)。

您可以使用以下函数检查当前读者的当前大小写转换策略readtable-case

> (readtable-case *readtable*)
:UPCASE
Run Code Online (Sandbox Code Playgroud)

要了解有关 readtable case 和 reader 如何交互的更多信息,请参阅Hyperspec 第 23.1.2 节中的讨论。