4

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

(defvar base-list (list (cons 'a 0) (cons 2 'c)))

assoc当我的论点是 type 时,我必须打电话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)

我尝试使用intern但得到NIL

CL-USER 29 : 1 > (assoc (intern "a") base-list)
NIL
4

2 回答 2

13

你想要的功能被称为read-from-string

CL-USER> (read-from-string "a")
A
1
CL-USER> (read-from-string "2")
2
1
CL-USER> 

请注意,在大多数实现中,基于使用internor的解决方案find-symbol不适用于表示数字的字符串(例如,“2”)。

于 2018-01-31T04:11:31.063 回答
4

你很亲近intern;你只是把案子弄错了。尝试这个:

> (assoc (intern "A") base-list)
(A . 0)

请注意,这里的 name-as-string 是大写的。

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

> (assoc (find-symbol "A") base-list)
(A . 0)

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

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

> (readtable-case *readtable*)
:UPCASE

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

于 2012-06-17T13:44:27.853 回答