让我们来看看Clojure代码:
(defn ^{:test-1 "meta-test-1"} fn-key-1
[x]
(eval nil))
(defn ^{:test-2 "meta-test-2"} fn-key-2
[x]
(eval nil))
(def some-map {fn-key-1 "test-1"
fn-key-2 "test-2"})
如您所见,我的地图的键是指向功能的符号。我不知道那里有什么特别的东西。
正如您所看到的,在定义地图时,我的地图的键是引用功能的符号。但是,当读者阅读它们时,它们就会被解析为函数对象。
现在,我想要做的是迭代我的some-map
地图以获取每个键的元数据。
(defn some-fn
[m]
(doseq [[fn-key value] m]
(println (meta fn-key))))
然而,这里印刷的是nil
。这是预期的,因为元数据定义了符号,而不是函数。因此,该函数没有附加元数据,这就是返回/打印nil
的原因。
所以这引出了一个问题:是否有可能获得引用我的功能的符号" fn-key"在那种情况下?
在该doseq循环中,似乎fn-key是一个函数,而不是该函数的符号。我需要的是一种获取该函数符号的方法,以便我可以使用(meta(get-symbol fn-key))。
通过以下方式定义函数来解决这个问题:
(def fn-key-1
(with-meta (fn [x] (eval nil)) {:foo "bar"}))
(def fn-key-2
(with-meta (fn [x] (eval nil)) {:foo "bar"}))
我修改了上面的解决方案,使其更清洁。实际上,如果要在REPL中键入fn-key-1
,则需要获得匿名函数引用,例如#< clojure.lang.AFunction$1@15ab1764>
。问题在于,当您不知道正在评估什么时,它会使调试变得困难。为解决此问题,我更改了两个函数定义以使用此语法来解决此问题:
(def fn-key-1 ^{:foo "bar"} (fn [x] (eval nil)))
(def fn-key-2 ^{:foo "bar"} (fn [x] (eval nil)))
现在,如果我们输入fn-key-1
,我们就会得到类似#<core$foo user.core$foo@66e37466>
的内容。至少,我们有名称空间&amp;此函数对象的符号签名。
答案 0 :(得分:1)
(def some-map {#'fn-key-1 "test-1"
#'fn-key-2 "test 2"})
阅读器将 fn-key-1
解析为函数对象(没有要查询的元数据)。 #'fn-key-1
解析为var
本身,并保存元数据。