如何从变量获取函数的元数据

KAR*_*ván 2 metadata clojure

我有一个可以在函数的元数据上工作的函数。我知道可以使用以下语法获取函数的元数据:

(meta #'println)
Run Code Online (Sandbox Code Playgroud)

它将返回我感兴趣的元数据:

{:arglists ([& more]), :doc "Same as print followed by (newline)", :added "1.0", :static true, :line 3631, :column 1, :file "clojure/core.clj", :name println, :ns #namespace[clojure.core]}
Run Code Online (Sandbox Code Playgroud)

但是,如果它在变量中,则它不起作用。我尝试了以下

(defn x [f] (meta #'f))
Run Code Online (Sandbox Code Playgroud)

当然,它会引发以下错误:

clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable to resolve var: f in this context, compiling:(/var/folders/zs/_8vy14592dncxyj8mcz4jfyc000_9z/T/boot.user1460390749042099586.clj:1:1)
             java.lang.RuntimeException: Unable to resolve var: f in this context
Run Code Online (Sandbox Code Playgroud)

如果我仅使用meta则无法正常工作:

(defn x [f] (meta f))
(x println)
Run Code Online (Sandbox Code Playgroud)

因为它返回的nil不是带有println函数的原始元数据。

当我尝试反引号时也是如此:

(defn x [f] (meta `f))
Run Code Online (Sandbox Code Playgroud)

Art*_*ldt 5

在这种情况下,您要查找的信息包含在包含函数的var中,而不是包含在函数中。

如果只给您一个容器的内容,则您将无法读取从容器中取出对象之前在盒子上写的内容。

  • 命名空间包含vars并为其命名
  • 变量具有关于它们包含的功能的元数据。
  • vars还拥有函数。

函数可以包含元数据,尽管您要查找的特定元数据位于var上的元数据中。

(meta #'symbol-here)
Run Code Online (Sandbox Code Playgroud)

在当前名称空间中查找与该符号关联的var symbol-here,然后查看该对象并从中获取元数据。

如果将var本身传递给函数f而不是传递其内容,则可以从该函数中查找元数据:

user> (defn x [f]
        (f "calling f with a string")
        (meta f))
#'user/x
user> (x #'println)
calling f with a string
{:arglists ([& more]), :doc "Same as print followed by (newline)", :added "1.0", :static true, :line 3631, :column 1, :file "clojure/core.clj", :        name println, :ns #namespace[clojure.core]}
Run Code Online (Sandbox Code Playgroud)

这里重要的一点是,您传递了实际上包含要查找的元数据的对象(变量),而不是容器中的对象(函数),也值得注意的是,如果您将var作为函数调用, var将使用相同的参数自动调用其包含的函数,并将响应传递回去。