【问题标题】:Difference between #^{...} and ^{...} metadata in Clojure?Clojure 中 #^{...} 和 ^{...} 元数据之间的区别?
【发布时间】:2013-03-24 01:48:54
【问题描述】:

考虑

(defn f ^{:foo "bar"} [x] (* x x))

(defn g #^{:foo "bar"} [x] (* x x))

编译和运行。

我有两个问题:第一,为什么(meta f)(meta g) 只产生nil?我原以为他们会产生{:foo "bar"}; i.o.w.,我是不是完全在元数据上吃午饭,我是否在那里定义了某种垃圾?

其次,元数据的两种语法有什么区别?看起来第二个是“tagged literal”,与edn, the extended data notation 有关,但如果没有更多上下文或示例,我无法完全理解它。

【问题讨论】:

    标签: clojure


    【解决方案1】:

    clojure 1.2 中的 #^ 元数据读取器宏 was replaced with ^。虽然目前两者之间没有区别,但旧形式已被弃用,您应该只使用^

    元数据文字应该在它要附加到的项目之前

    (defn ^{:foo "bar"} f [x] (* x x))
    

    要记住的另一件事是,上述定义中的元数据没有附加到函数,它附加到引用函数的var。您可以通过以下方式获取f var 的元数据:

    (meta (var f))
    

    或者使用var阅读器宏:

    (meta #'f)
    

    【讨论】:

    • 感谢您的出色回答。我正在查看(doc defn),它说名称位于元数据之前,除非我误读了文档:“clojure.core/defn ([name doc-string?attr-map?[params*] prepost- map?body] [name doc-string?attr-map?([params*] prepost-map?body) + attr-map?])"
    • attr-mapdefn 宏的一个特殊功能,它应该使将元数据附加到正在定义的 var 上更容易。使用attr-map 时,您不应在地图前加上^ ((defn f {:foo "bar"} [] :baz))。我还没有真正看到它在任何地方使用过,使用^ 阅读器宏更为常见。我猜attr-map 在旧版本的 clojure 中很有用,因为使用元数据不太漂亮,但是现在使用 ^{:foo "bar} 形式更加惯用和更通用(你可以将它放在任何可以保存元数据的对象之前) .
    猜你喜欢
    • 1970-01-01
    • 2011-06-11
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 2018-05-08
    • 2016-12-05
    • 2015-10-05
    相关资源
    最近更新 更多