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

时间:2012-06-17 11:33:52

标签: lisp common-lisp symbols

我在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

2 个答案:

答案 0 :(得分:5)

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

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

请注意,基于使用internfind-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.

中的讨论