我正在尝试向 Clojure 时间宏添加一个选项“消息”属性。基本上我想在时间的输出中添加一个可选的自定义消息。我试图在我的程序中找到一个瓶颈,并且将一些描述性消息附加到时间的输出会非常有帮助。
我尝试了以下方法:
;optional argument
(defmacro time
"Evaluates expr and prints the time it took. Returns the value of
expr."
{:added "1.0"}
[expr & msg]
`(let [start# (. System (nanoTime))
ret# ~expr]
(prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs. " (first ~msg)))
ret#))
和
(defmacro time
"Evaluates expr and prints the time it took. Returns the value of
expr."
{:added "1.0"}
([expr] (time expr ""))
([expr msg]
`(let [start# (. System (nanoTime))
ret# ~expr]
(prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs. " ~msg))
ret#)))
两者都抛出异常。我如何使这项工作?
最佳答案
它抛出异常,因为 msg 是一个列表,
说你叫它,
(time (+ 1 1) "asd")
宏中的 msg 成为失败的函数调用(“asd”)。只是解构消息,
[expr & [msg]]
并使用
~msg
您还可以使用 macroexpand 测试宏是如何扩展的,
(macroexpand '(time (+ 1 1) "asd"))
还有几点,
编辑:带有可选消息的时间,
(defmacro time
"Evaluates expr and prints the time it took. Returns the value of
expr."
{:added "1.0"}
[expr & [msg]]
(let [msg (if (nil? msg) "" msg)]
`(let [start# (. System (nanoTime))
ret# ~expr]
(prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs. " ~msg))
ret#)))
(time (+ 1 1))
"Elapsed time: 0.068 msecs. "
2
(time (+ 1 1) "asd")
"Elapsed time: 0.067 msecs. asd"
2
关于macros - 向宏添加可选参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7134094/