说我有以下代码:
(defn ^ {:graph-title“ Function 1”} func-1[X](用x做某事)(defn get-graph-title[功能](str((元功能):图标题)))
我希望它返回“功能1”,但它返回nil。我认为这是由以下差异引起的,我并不完全理解:
(元func-1)=> {:ns some-ns-info,:name func-1}(元#'func-1)=> {:ns some-ns-info,:name func-1,:graph-title“ Function 1”}
有人可以向我解释吗?
元数据附加到变量,而不附加到函数。
因此,要获取图形标题,您必须从var的元数据中获取条目:graph-title
。您如何看待您的宏?
(defmacro get-graph-title
[func]
`(:graph-title (meta (var ~func))))
(get-graph-title func-1)
=> "Function 1"
[ func-1
上有元数据,Var #'func-1
上有元数据,符号 'func-1
上有元数据。 Clojure阅读器宏^
在读取时将元数据添加到symbol。 defn
宏在编译时将元数据从symbol复制到Var。
defn
还将一些标准Var
元数据复制到function:Clojure 1.2.0
user=> (defn ^{:foo :bar} func-1 [] nil)
#'user/func-1
user=> (meta func-1)
{:ns #<Namespace user>, :name func-1}
user=> (meta #'func-1)
{:foo :bar, :ns #<Namespace user>, :name func-1, ...
但是,在当前的Clojure 1.3快照中,defn
不会将任何元数据复制到该函数:
Clojure 1.3.0-master-SNAPSHOT user=> (defn ^{:foo :bar} func-1 [] nil) #'user/func-1 user=> (meta func-1) nil user=> (meta #'func-1) {:foo :bar, :ns #<Namespace user>, :name func-1, ...
通常,如果要获取定义的元数据,则需要元数据放在上。Var
symbol func-1中指定的元数据将通过def特殊形式复制到名为func-1的var。请参阅http://clojure.org/special_forms中的def文档
当评估func-1
时,这是绑定到var的符号,则得到var的value
(在这种情况下为函数对象)。参见http://clojure.org/vars功能对象本身不会自动接收在符号/变量上手动指定的元数据。因此,所需的信息根本不在功能中。它在var中,您必须指定您确实需要var func-1
本身而不是其值。这就是(var func-1),和等效的快捷方式#'func-1一样。
据我所知,当defn
求值时,它将生成一个名称与(munge fn-symbol)
相同的类。有一个称为demunge
的函数将为我们反向执行此操作。因此,从Fn对象的类名中,我们可以找到符号,从符号中,我们可以找到var。
(-> (class some-fn)
(print-str)
(demunge)
(symbol)
(find-var)
(meta)
(:doc))
非常有趣的是,demunge
和clojure.main
中都可以找到clojure.repl
,它们的作用完全相同,因此可以随意要求其中的任何一个进行入库:
(require '[clojure.main :refer (demunge)]) ;; or (require '[clojure.repl :refer (demunge)])