【问题标题】:Constant definition in ClojureClojure 中的常量定义
【发布时间】:2012-02-07 14:08:57
【问题描述】:

我正在尝试定义一个宏来定义 Clojure 1.3 中添加的编译时常量语法:

== 2.14 ^:const defs ==

^:const 让您可以更快地引用原始值。

(定义常量 {:pi 3.14 :e 2.71})

(def ^:const pi (:pi 常量)) (def ^:const e (:e 常量))

在映射中查找 :e 和 :pi 的开销发生在编译时 时间,因为 (:pi 常数) 和 (:e 常数) 在它们的 评估父 def 表单。

基本上我想要(def ^:const ... ...) 周围的一些语法糖,所以我尝试这样做:

(defmacro defconst [const-name const-val]
  `(def ^:const ~const-name ~const-val))

但这不起作用:

user=> (macroexpand '(defconst pi 3.14))
(def pi 3.14)

据我所知,#^<...> 元快捷方式是一个阅读器宏,要定义一个向某物添加一些元数据的宏,应该使用(with-meta ...)。

我没有找到任何关于 ^:const 的文档。这种句法结构甚至会创建某种元数据吗?以下示例未显示任何内容:

user=> (def ^:const pi 3.14)
#'user/pi
user=> (meta pi)
nil

【问题讨论】:

    标签: macros clojure


    【解决方案1】:

    第一个问题是您正在检查3.14 的元数据。使用(meta (var pi)) 查看pi 的元数据。如果这样做,您将看到它包含:const true。

    (defmacro defconst [const-name const-val]
      `(def
        ~(with-meta const-name
           (assoc (meta const-name) :const true))
        ~const-val))
    

    准确复现^:const的元数据和性能(代码改编自defn-的源代码)。

    【讨论】:

    • 感谢您的回答。我通过 (time (dotimes [_ 1e10] (* pi pi))) 与 (time (dotimes [_ 1e10] (* 3.14 3.14))) 进行了检查,执行时间相同。
    • 有趣。我错过了const 的要点——我没有注意到const“vars”的查找效率更高。现在,它们更有意义了。
    猜你喜欢
    • 2016-06-03
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多