以下示例取自《Clojure编程》第二版:
(defn ^{:tag String} shout [^{:tag String} s] (.toUpperCase s))
什么是:tag元数据的价值? 执行以下操作:
((map #'shout) :tag)
产生的结果是 java.lang.String,但如果我不能区分输入和输出参数,那么到底传达了什么信息呢?
以下示例取自《Clojure编程》第二版:
(defn ^{:tag String} shout [^{:tag String} s] (.toUpperCase s))
((map #'shout) :tag)
产生的结果是 java.lang.String,但如果我不能区分输入和输出参数,那么到底传达了什么信息呢?
我在阅读第三版《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)
... returns
{:tag java.lang.String,
:arglists ([s]),
etc... }
(defn ^String strneg [^Double n] (str (- n)))
(meta #'strneg)
; => {:tag java.lang.String, :arglists ([n]), ... ... }
与之比较:
(meta (first (first (:arglists (meta #'strneg)))))
; => {:tag Double}
因此,当您在函数上使用元标记时,标签是该函数返回值的类型提示
^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.
Clojure supports the use of type hints to assist the compiler
in avoiding reflection in performance-critical areas of code.
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
是相同的。