【问题标题】:Having trouble with clojure macroclojure 宏遇到问题
【发布时间】:2014-01-15 23:22:03
【问题描述】:

我正在尝试编写一个宏,可用于在新线程上调用函数,并在运行后打印函数的名称以及线程的名称。

到目前为止,我拥有的是:

     (defmacro start-threads [f]
        '(let [t (Thread. 'f)]
            (prn (str "running " 'f " on: " (.getName t)))))

当我运行时:

    (start-threads funcname)

输出:“在线程 47 上运行 f”。我希望它输出:“在线程47上运行funcname。当我尝试取消引用它时,它会尝试评估函数。我知道我没有在这里的线程上运行.start,但我应该能够添加之后。我确定宏在这里不是完全必要的,我主要是出于好奇而想知道,因为我刚刚开始思考 clojure 中的宏是如何工作的。

【问题讨论】:

    标签: macros clojure


    【解决方案1】:

    基本上,您想要的是语法引用而不是普通引用。

    (defmacro start-threads [f]
      `(let [t# (Thread. ~f)]
        (prn (str "running " '~f " on: " (.getName t#)))))
    

    ~f 在语法引用中插入 f 的值,'~f 引用该值,t# 生成自动生成符号,因此变量名称不会与任何周围的名称冲突。

    但正如您正确指出的那样,您确实不需要宏。它很容易成为一个函数:

    (defn start-threads [f]
      (let [t (Thread. f)]
        (prn (str "running " f " on: " (.getName t)))))
    

    【讨论】:

    • 谢谢,这绝对有帮助。我想我想要的一件事不是获得函数的字符串表示,它看起来像 data_staging.main$write_thread@52a731cb,而是我想要输入的实际文本作为宏的参数。所以 (start-thread write-thread) 会输出“running write-thread on: Thread-47”。显然没什么大不了的,我只是好奇如何做到这一点。
    • @SeanGeoffreyPietz:啊,我明白了。好的,我已经将代码更改为以这种方式工作。唯一的区别是你只需要引用第二个~f。这你需要一个宏来做的事情,因为参数将在它们传递给的函数执行之前被评估。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多