2013-03-25 83 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})