我在Common Lisp中有这个关联列表:
(defvar base-list (list (cons 'a 0) (cons 2 'c)))
当我的论证类型为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)
我尝试使用intern
,但获得NIL
:
CL-USER 29 : 1 > (assoc (intern "a") base-list)
NIL
答案 0 :(得分:5)
您想要的功能称为read-from-string
:
CL-USER> (read-from-string "a")
A
1
CL-USER> (read-from-string "2")
2
1
CL-USER>
请注意,基于使用intern
或find-symbol
的解决方案对于大多数实现中代表数字的字符串(例如" 2")不起作用。
答案 1 :(得分:1)
你和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-case *readtable*)
:UPCASE
要详细了解可阅读案例与读者的互动方式,请参阅section 23.1.2 of the Hyperspec.
中的讨论