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

Posted

技术标签:

【中文标题】如何将字符串转换为符号以用作 Lisp“assoc”函数中的键?【英文标题】:How do I convert a string to a symbol for use as a key in the Lisp "assoc" function? 【发布时间】:2012-06-19 17:20:31 【问题描述】:

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

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

当我的参数类型为 string 时,我必须调用 assoc

对于(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

【问题讨论】:

嗯..这很相似,但不起作用!! ***.com/questions/9812393/… 退出调试器。 NUMBER-TO-SYMBOL 部分没有意义,因为数字 2 不是符号。 【参考方案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

要了解有关 readtable 案例和阅读器如何交互的更多信息,请参阅section 23.1.2 of the Hyperspec. 中的讨论

【讨论】:

【参考方案2】:

你要的函数叫read-from-string

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

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

【讨论】:

以上是关于如何将字符串转换为符号以用作 Lisp“assoc”函数中的键?的主要内容,如果未能解决你的问题,请参考以下文章

在 Common Lisp 中将 FUNCTION 转换为 STRING 或 SYMBOL

如何在lisp中以指定格式将数字打印为浮点数?

如何以优雅有效的方式将无符号/有符号整数/长整数转换为 C 字符串?

Common Lisp宏变量扩展

将 xsl:apply-templates 转换为字符串值以用作 if 参数

将 Common Lisp 中的宏参数视为(区分大小写的)字符串