Parsing 如何在Clojure中将param变量解析为符号?

Parsing 如何在Clojure中将param变量解析为符号?,parsing,variables,clojure,compilation,scope,Parsing,Variables,Clojure,Compilation,Scope,我想将一个符号作为参数传递给函数,并将该符号捕获为引号或字符串,以便它可以与末尾标记的-a连接,然后使用新生成的符号定义一个原子。但是,在对符号进行求值之前,有什么方法可以做到这一点吗 (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))))

我想将一个符号作为参数传递给函数,并将该符号捕获为引号或字符串,以便它可以与末尾标记的
-a
连接,然后使用新生成的符号定义一个原子。但是,在对符号进行求值之前,有什么方法可以做到这一点吗

(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))))

对符号求值时,将在当前绑定上下文中解析该符号,除非您明确禁止使用
quote
或其缩写
'
进行求值

e、 g:

(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
作为宏写入


我根本不推荐用这种方法来解决您的问题。

(名称(符号“x”);这就是你的意思吗?那不行。你能告诉我应该在哪里使用它吗?我最终使用了带有:通道和:缓冲区键的地图。:buffer值是一个包含一个向量的原子,该向量可以被交换-通过特殊功能,每当进行put或take时,都会使用conj或pop进行编辑。我问这个问题的一个原因是想看看我之前考虑的事情是否能够实现。我想答案是“只有宏”。谢谢你的反馈。嘿,伙计,很抱歉打扰你,但是如果你能看一下我问题的编辑并重新制定你的答案,我将非常感激。我试着把它缩小到我真正想要的范围,因为我仍然觉得在Clojure的不同时期可能有一些东西我没有掌握。再次感谢。你的宏应该可以正常工作。您不必以
#
结束符号,因为它不属于计算前宏返回的表单(引用表单)的一部分。如果符号将被绑定到宏返回的表单中,则只能使用以
#
结尾的符号-它们将被通过
gensym
生成的符号替换,您不必担心它们会隐藏在其他绑定中。由于您在其中解压缩了
new sym#
,因此它不会成为返回表单的一部分,因此您可以将其称为
new sym
。好的,谢谢。我想这确实突出了宏的实用性:它们可以真正去到以前没有函数去过的地方。请注意gen-syms。您可以在计算代码之前使用它们转换代码。它还强调了Lisps“代码作为数据”的实用性:您可能想要签出