【问题标题】::tag metadata clojure:tag 元数据clojure
【发布时间】:2012-12-20 13:02:46
【问题描述】:

在以下示例中(取自Programming Clojure, 2nd ed 书籍:

(defn ^{:tag String} shout [^{:tag String} s] (.toUpperCase s))

:tag 元数据的价值是什么? 做一个:

((map #'shout) :tag)

yields java.lang.String 但是如果我无法区分输入和输出参数,究竟传达了什么信息?

【问题讨论】:

    标签: clojure metadata


    【解决方案1】:

    我在阅读第三版 Programming Clojure 时遇到了同样的问题,该版本的示例略有更新:

    (defn ^{:tag String} shout [^{:tag String} s] (clojure.string/upper-case s))
    

    相当于简写形式:

    ; I guess tags and type hints are equivalent
    (defn ^String shout [^String s] (clojure.string/upper-case s))
    

    就像你说的,如果你查找函数元数据,如果标签是指输入或输出参数,那么它是不明确的:

    (meta #'shout)
    

    ...返回

    {:tag java.lang.String,
     :arglists ([s]),
     etc... }
    

    如果您考虑一下,它必须是返回类型,因为函数可以有 N 个参数,但 Clojure 不允许多个返回值。元数据中的 :tag 不是向量,而是单个值。

    如果您实际上以编程方式需要函数参数的标记/类型提示,您可以调用 :arglists 上的元函数,如下所示:

    https://stackoverflow.com/a/26116353/695318

    【讨论】:

      【解决方案2】:

      :tag 元数据的价值是什么?

      我找到了一个clojure官方文档

      Clojure - Metadata

      ^String obj - Sets the value of :tag key in the object’s metadata.
      Equivalent to ^{:tag java.lang.String} obj
      Used to hint an objects type to the Clojure compiler. 
      See Java Interop: 
        Type Hints for more information and a complete list of special type hints.
      

      Type Hints

      Clojure supports the use of type hints to assist the compiler 
      in avoiding reflection in performance-critical areas of code.
      

      如果我无法区分输入和输出参数,究竟传达了什么信息?

      您不需要指定输入或输出参数的类型。并且,如果未指定,clojure 将使用反射执行函数(根据此描述)。

      还有另一个blog post。 根据这篇文章,Clojure 正在为 Clojure 代码创建的所有方法使用 IFn 接口。

      IFn defines all arguments of .invoke to be of type Object.
      So you can pass anything you like to a Clojure function.
      It doesn't matter which type it is, because everything is an Object anyway. 
      

      所以,我觉得调用没有类型提示的Clojure方法和调用Java的反射.invoke是一样的。

      【讨论】:

        猜你喜欢
        • 2011-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多