2014-05-13 38 views
1

我想將符號作爲參數傳遞給函數,並將該符號捕獲爲帶引號的字符串或字符串,以便可以在末尾標記爲-a,然後使用新生成的符號定義原子。但是在符號被評估之前有沒有辦法做到這一點?如何在Clojure中將參數變量解析爲符號?

(defn sym-a [variable] (symbol (str variable "-a"))) 


    (defn sym-val [old-sym] 
     (let [ new-sym (sym-a old-sym)] 
     `(def ~new-sym (atom nil)))) 

它適用於我使用宏時,但我不知道是否有某種方法可以避免這種情況?

(defmacro sym-val [old-sym] 
    (let [ new-sym (sym-a old-sym)] 
    `(def ~new-sym (atom nil)))) 
+0

(name(symbol「x」));你是這個意思嗎? – dsm

+0

這不起作用。你能告訴我應該在哪裏使用它嗎? – kurofune

回答

2

當一個符號被評估,這在當前綁定上下文得到解決,除非你明確地防止使用評價或quote其簡寫'

例如爲:

(def foo-log 42) 
(log-name foo) 
;; CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(/tmp/form-init735849253251327390.clj:1:1) 

(log-name 'foo) 
=> foo-log 

(eval (log-name 'foo)) 
=> 42 

你可以寫一個宏,在未評估的參數列表,並返回所創建的符號進行評估。

(defmacro log-name-macro 
    [channel-name] 
    (log-name channel-name)) 

(log-name-macro foo) 
=> 42 

在您的示例中,您現在需要將log-put寫爲宏。

我不建議這種方法來解決您的問題。

+0

我最終使用了一個帶有:channel和:緩衝區鍵的地圖。 The:buffer value是一個包含一個vector的atom,它通過特殊的函數在put或take的時候通過一個conj或者pop來交換。我問這個問題的一個原因是要看我以前考慮的事情是否能夠完成。我想這個答案是「只用宏」。感謝您的反饋意見。 – kurofune

+0

嘿,我很抱歉打擾你,但如果你可以看看我的問題的編輯,並重新形成你的答案,我會非常感激。我試圖將其縮小到我真正想得到的東西,因爲我仍然覺得在Clojure中可能有些事情我不瞭解不同時期。再次感謝。 – kurofune

+0

你的宏應該可以正常工作。您不必使用'#'結束符號,因爲它不會成爲評估之前宏返回的表單的一部分(引用的表單)。只有在你的宏返回的表單中綁定了符號時,才應該使用以'#'結尾的符號 - 它們將被替換爲通過'gensym'生成的符號,並且您不必擔心它們會影響其他綁定。由於您在其中引用了'new-sym#',因此它不會成爲返回表單的一部分,因此您可以將其稱爲'new-sym'。 –