2013-03-25 71 views
3

所以我想将一个函数传递给def的“名称”部分。 的问题是: “到DEF第一个参数必须是一个符号”用动态名称定义一个值

我试图比如做:

(def serverNumber 5) 
(def (str "server" serverNumber) {:id serverNumber :value 4939}) 

但我不能找到annnnnnny办法做到这一点。任何帮助将不胜感激:)

+2

使用动态名称(在大多数语言/场景)往往是错误的* *方法..怎么会这样的值是[均匀]后访问?请参阅[Clojure数据结构](http://clojure.org/data_structures)中的“地图”以获取替代方案。 – 2013-03-25 23:39:06

+0

(术语“变量变量”通常与PHP相关联,但与它在这里提到的内容有关。) – 2013-03-25 23:45:10

回答

3

首先,我必须指出,这似乎是一个坏主意。你为什么试图用动态生成的名字生成def? (As @ pst已经指出,映射是通过动态生成标识符创建绑定的常用解决方案。)

假设您有这样做的合法原因(也许它是某些库函数的一部分,用户),您可以用宏实现这一点:

(defmacro def' [sym-exp & other-args] 
    `(def ~(-> sym-exp eval symbol) [email protected])) 

(def serverNumber 5) 
(def' (str "server" serverNumber) {:id serverNumber :value 4939}) 

请注意,这仅适用于顶层(因为宏是在编译时运行)。如果你想这样做,在一个函数或东西,那么你只需要使用eval:

(defn def'' [sym-exp & other-args] 
    (eval `(def ~(-> sym-exp eval symbol) [email protected]))) 

如果你只是想创建一堆的药,也许这样的事情会工作:

(def servers 
    (vec (for [i (range 5)] 
     {:id i :value 4939}))) 

然后你就可以通过索引只是访问它们:

(servers 0) 
; => {:id 0, :value 4939} 
+0

嘿,我想要做的是创建具有不同名称的多个代理。我想创建6个类型为“服务器”的代理,因此每个代理都有名称: server0 。 。 server5 – 2013-03-26 00:04:02

+1

@FengHuo - 如果你只是想生成一堆“服务器”变量,为什么不把它们放在向量中?我会用一个例子更新我的答案。 – DaoWen 2013-03-26 00:09:43

1

def运行时当量是intern

(intern *ns* 
     (symbol (str "server" server-number)) 
     {:id server-number :value 4939})