从Lisp中的一个字符串创建一个变量名
问题描述:
我想要一个字符串,并将其转换为变量名。我虽然(制造符号)或(实习生)会这样做,但显然它不是我想要的,或者我错误地使用它。从Lisp中的一个字符串创建一个变量名
例如:
> (setf (intern (string "foo")) 5)
> foo
5
在这里,我将试图创建一个名为“富”变量与5.除一个值,上面的代码给我一个错误。我在找什么命令?
答
有许多事情要考虑这里:
SETF
不评价它的第一个参数。它期望一个符号或一个指定要更新位置的表单。改为使用SET
。根据您的Common Lisp实现的年份和设置,符号名称可能默认为大写。因此,对
foo
的第二次引用实际上可能指的是名称为"FOO"
的符号。在这种情况下,您需要使用(intern "FOO")
。对
STRING
的调用是无害但不必要的,如果该值已经是一个字符串。
全部放在一起,试试这个:
> (set (intern "FOO") 5)
> foo
5
答
用途:
CL-USER 7 > (setf (SYMBOL-VALUE (INTERN "FOO")) 5)
5
CL-USER 8 > foo
5
这也适用于一个变量:
CL-USER 11 > (let ((sym-name "FOO"))
(setf (SYMBOL-VALUE (INTERN sym-name)) 3))
3
CL-USER 12 > foo
3
也是记住默认符号在内部以大写形式创建。如果要通过字符串访问符号,则必须使用大写字符串。
嘿,工作!好吧,有点。实际上我并没有试图用(set)赋值,而是使用另一个我没有创建的函数(add-dm)。显然,(add-dm)与(setf)具有相同的限制,其中第一个表达式不被评估,所以我必须找出另一种方法。但是这确实揭示了一些事情,所以谢谢! (另外,我意识到(字符串)是不必要的,尽管我的最终目标是从串联字符串创建一个符号,所以我保留它以防万一它有所作为)。 – Jeff 2011-03-15 02:48:13
@Jeff如果'ADD-DM'是一个宏,它可能扩展为一个导出的函数,可以像'SET'一样使用。尝试检查'(macroexpand-1'(add-dm ...))'的结果,看看你是否幸运。 – WReach 2011-03-15 03:12:47
SET不是必需的。 – 2011-03-15 21:16:30