:标签元数据clojure

时间:2013-01-06 18:09:47

标签: clojure metadata

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

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

:tag 元数据的价值是多少? 做一个:

((map #'shout) :tag)

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

2 个答案:

答案 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上调用元函数,如下所示:

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

答案 1 :(得分:0)

  

标签元数据的价值是什么?

我找到了一份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正在使用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是相同的。