Clojure:在循环上下文中获取函数的符号的问题 [英] Clojure: issues getting the symbol of a function in a looping context

查看:257
本文介绍了Clojure:在循环上下文中获取函数的符号的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们来看一下Clojure代码:

Let's take that Clojure code:

  (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"})

正如你所看到的,我的地图的键是符号指功能。我不知道有什么特别的地方。

正如你可以看到,当定义地图时,我的地图的键是符号, 。然而,当他们被读者读取,然后他们得到解决到函数对象。

As you can see, when defining the map the keys of my map are Symbols that refers to functions. However, when they are read by the reader, then they get resolved to the function objects.

现在,我想做的是迭代我的<$ c $

Now, what I want to do is to iterate over my some-map map to get the meta-data for each of the keys.

我在想这样做:

  (defn some-fn 
    [m]
    (doseq [[fn-key value] m]
      (println (meta fn-key))))

nil 。这是期望的,因为元数据定义符号,而不是函数。因此,没有元数据附加到函数,这是为什么 nil 正在返回/打印。

However, what is being printed here is nil. This is expected since the meta-data is defining the symbol, and not the function. So, there is no meta-data attached to the function and it is why nil is being returned/printed.

因此,这导致一个问题:是否有可能获得引用我的函数fn-key在那个上下文中的符号?

So this lead to a question: is it possible to get the symbol that refers to my function "fn-key" in that context?

在doseq循环中出现fn-key是一个函数,而不是该函数的符号。我需要的是一个方法来获取该函数的符号,以便我可以使用(meta(get-symbol fn-key))。

In that doseq loop, it appears that fn-key is a function and not the symbol of that function. What I need is a way to get the symbol of that function such that I can use (meta (get-symbol fn-key)).

这个问题通过定义函数来解决:

This question got resolved by defining the functions that way:

(def fn-key-1
  (with-meta (fn [x] (eval nil)) {:foo "bar"}))

(def fn-key-2
  (with-meta (fn [x] (eval nil)) {:foo "bar"}))



< h2>修正解决方案

我修改了上述解决方案,使其更清洁。事实上,如果你在REPL中输入 fn-key-1 ,你会得到一个匿名函数引用,例如#< clojure.lang.AFunction$1@15ab1764> 。问题是,当你不知道正在评估什么时,它使事情难以调试。为了解决这个问题,我改变了两个函数定义来使用这个语法,这解决了这个问题:

Revision of the Resolution

I revised the solution above to make it cleaner. In fact, if you were to type fn-key-1 in the REPL, you were to get an anonymous function reference such as #< clojure.lang.AFunction$1@15ab1764>. The problem with that is that it make things difficult to debug when you don't know what is being evaluated. To solve this issue, I changed the two function definitions to use this syntax, which resolve this issue:

(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> 的东西。至少,我们有命名空间&此函数对象的符号签名。

Now, if we type fn-key-1 then we will get something like #<core$foo user.core$foo@66e37466> instead. At least, we have the namespace & symbol signature of this function object.

推荐答案

(def some-map {#'fn-key-1 "test-1"
               #'fn-key-2 "test 2"})

fn-key-1 由读取器解析为函数对象(没有要查询的元数据)。 #'fn-key-1 解析为 var 本身,并保存元数据。

fn-key-1 is resolved by the reader to the function object (which has no metadata to query). #'fn-key-1 resolves to the var itself, and holds the metadata.

这篇关于Clojure:在循环上下文中获取函数的符号的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆