2009-07-24 18 views
29

你是如何在Clojure程序中使用元数据的?Clojure元数据的一些用途是什么?

我看到编程Clojure的一个例子:

(defn shout [#^{:tag String} message] (.toUpperCase message)) 
;; Clojure casts message to String and then calls the method. 

都有些什么用途?这种编程形式对我来说是全新的。

回答

1

元数据被编译器广泛用于存储对象类型等内容。
你,当你给类型提示

(defn foo [ #^String stringy] .... 

我已经用它的东西像存储已添加了一些填充量使用。它的目的是提供与数据“正交”的信息,在决定数值是否相同时不应考虑。

24
  • Docstrings作为元数据存储在:doc密钥下。这可能是元数据使用最多的数字1。
  • 可以选择使用元数据标记返回值和参数类型,以避免在运行时反映类型的开销,从而提高性能。这些也被称为“类型提示”。 #^String是一种类型提示。
  • 存储“引擎盖下”供编译器使用的内容,例如函数的arglist,已定义var的行号或var是否保存对宏的引用。这些通常由编译器自动添加,通常不需要由用户直接操作。
  • 创建测试用例简单的函数定义的一部分:

    (defn #^{:test (fn [] (assert true))} something [] nil)

    (test #'something)

如果你正在读编程Clojure的,那么第2章提供了一个很好的介绍,以元数据。图2.3提供了常用元数据的一个很好的总结。

14

多样性的一些答案,不专注于互动与语言本身:

你也可以如。跟踪一些数据的来源。未检查的输入标记为:tainted。验证器可能会检查一些事情,然后将状态设置为:clean。执行安全相关事项的代码然后可以在:tainted上禁止并仅接受:clean ed输入。

5

元数据对我来说是非常有用的打字目的。我所说的不仅仅是类型提示,而是关于完整的自定义类型系统。最简单的例子 - 超载对于结构印刷方法(或任何其他VAR):

(defstruct my-struct :foo :bar :baz) 

(defn make-my-struct [foo bar baz] 
    (with-meta (struct-map my-struct :foo foo :bar baz :baz baz) 
     {:type ::my-struct})) 


(defmethod print-method 
    [my-struct writer] 
    (print-method ...)) 

在一般情况下,一起使用Clojure验证功能,它可以提高安全性,并在同一时间,你的代码的灵活性非常非常(尽管实际编码需要一些时间)。请参阅types-api