2011-03-15 220 views
8

我想要一个字符串,并将其转换为变量名。我虽然(制造符号)或(实习生)会这样做,但显然它不是我想要的,或者我错误地使用它。从Lisp中的一个字符串创建一个变量名

例如:

> (setf (intern (string "foo")) 5) 
> foo 
    5 

在这里,我将试图创建一个名为“富”变量与5.除一个值,上面的代码给我一个错误。我在找什么命令?

回答

10

有许多事情要考虑这里:

  1. SETF不评价它的第一个参数。它期望一个符号或一个指定要更新位置的表单。改为使用SET

  2. 根据您的Common Lisp实现的年份和设置,符号名称可能默认为大写。因此,对foo的第二次引用实际上可能指的是名称为"FOO"的符号。在这种情况下,您需要使用(intern "FOO")

  3. STRING的调用是无害但不必要的,如果该值已经是一个字符串。

全部放在一起,试试这个:

> (set (intern "FOO") 5) 
> foo 
    5 
+0

嘿,工作!好吧,有点。实际上我并没有试图用(set)赋值,而是使用另一个我没有创建的函数(add-dm)。显然,(add-dm)与(setf)具有相同的限制,其中第一个表达式不被评估,所以我必须找出另一种方法。但是这确实揭示了一些事情,所以谢谢! (另外,我意识到(字符串)是不必要的,尽管我的最终目标是从串联字符串创建一个符号,所以我保留它以防万一它有所作为)。 – Jeff 2011-03-15 02:48:13

+2

@Jeff如果'ADD-DM'是一个宏,它可能扩展为一个导出的函数,可以像'SET'一样使用。尝试检查'(macroexpand-1'(add-dm ...))'的结果,看看你是否幸运。 – WReach 2011-03-15 03:12:47

+2

SET不是必需的。 – 2011-03-15 21:16:30

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 

也是记住默认符号在内部以大写形式创建。如果要通过字符串访问符号,则必须使用大写字符串。

相关问题