在以下示例中(摘自Programming Clojure, 2nd ed书:
(defn ^{:tag String} shout [^{:tag String} s] (.toUpperCase s))
:tag 元数据的价值是多少? 做一个:
((map #'shout) :tag)
产生 java.lang.String ,但是如果我无法区分输入和输出参数,那么究竟是什么信息会被传达?
答案 0 :(得分: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不允许多个返回值。元数据中的:标签不是矢量而是单个值。
如果您实际上以编程方式需要函数参数的标记/类型提示,则可以在:arglists上调用元函数,如下所示:
答案 1 :(得分:0)
标签元数据的价值是什么?
我找到了一份clojure官方文件
^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.
如果我无法区分输入和输出参数,究竟会传达什么信息?
您无需为输入或输出参数指定类型。并且,如果没有指定,clojure将使用反射执行该函数(根据此描述)。
还有另一个blog post。 根据这篇文章,Clojure正在使用IFn接口来处理Clojure代码创建的所有方法。
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
是相同的。