如何唯一标识给定的 clojure 函数?

How to uniquely identify a given clojure function?

我目前正在为我用 clojure 编写的扫雷游戏开发一个简单的事件调度程序。

作为起点,我考虑过类似的东西:

(def receivers (atom {}))

使用注册函数将给定函数附加到特定事件映射,每个事件都有一个嵌套集,例如{:do-sth #{func1 func2}}

据我了解,一旦您再次向命名空间添加一个函数,它就会具有不同的身份,这当然是有道理的,但让我的方法失败了。

有没有办法唯一标识一个可能作为参数传入的函数?否则,我必须为每个我想尽可能避免的功能提供一个唯一的 ID。

更新

根据 clyfe 的建议,我最终采用了以下第一种方法:

(def receivers (atom {}))

(defn register 
  [event wrapped-function]
  (if 
    (var? wrapped-function)    
    (swap! receivers 
           #(assoc %1 %2 (conj (or (get %1 %2) #{}) %3))
           event 
           wrapped-function)
    (throw (IllegalStateException. 
            "wrapperd function must be a var"))))


(defn bar
  []
  "bar")


(register :foo #'bar)

如果问题是由于代码重新加载引起的,您可以将函数的封闭 var 存储在集合 {:ev #{#'f1 #'f2}} 中,重新加载后保持不变:

user=> (defn foo [] 1)
#'user/foo
user=> foo
#<user$foo user$foo@540e6cef>
user=> (def f1 foo)
#'user/f1
user=> (def f2 #'foo)
#'user/f2
user=> (defn foo [] 2)
#'user/foo
user=> foo
#<user$foo user$foo@35d4a23f>
user=> (f1)
1
user=> (f2)
2