向宏添加可选参数

发布于 2024-11-30 11:54:27 字数 870 浏览 1 评论 0原文

我正在尝试向 Clojure 时间宏添加一个选项“message”属性。基本上我想向时间输出添加可选的自定义消息。我试图找到程序中的瓶颈,并且在时间输出中附加一些描述性消息将非常有帮助。

我已经尝试过以下操作:

;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#)))

两者都抛出异常。我该如何进行这项工作?

I'm trying to add an option "message" attribute to the Clojure time macro. Basically I want to add an optional custom message to the output of time. I'm trying to find a bottleneck in my program and having some descriptive messages attached to time's output would be very helpful.

I've tried the following:

;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#))

and

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

Both throw exceptions. How do I make this work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

对你而言 2024-12-07 11:54:27

它会引发异常,因为 msg 是一个列表,

假设您使用宏调用它,

(time (+ 1 1) "asd")

宏中的 msg 变成函数调用(“asd”),该函数调用失败。只需解构 msg,

 [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

It throws an exception because msg is a list,

say you call it with,

(time (+ 1 1) "asd")

msg in the macro becomes a function call, ("asd") which fails. Just destructure msg,

 [expr & [msg]]

and use

 ~msg

You can also test how macros are expanded with macroexpand,

(macroexpand '(time (+ 1 1) "asd"))

Also couple of points,

  • time is already in core
  • your version only accepts and times a single expression.

EDIT: time with optional message,


(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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文