如何在Clojure中将函数的名称作为字符串?
到目前为止我所看到的并不像惯用语:
(defn fn-name
[f]
(first (re-find #"(?<=\$)([^@]+)(?=@)" (str f))))
(defn foo [])
(fn-name foo) ;; returns "foo"
Run Code Online (Sandbox Code Playgroud)
编辑:通过提供的提示,我把一个基本的宏放在一起,做我想要的.它看起来更好吗?
(defmacro fn-name
[f]
`(-> ~f var meta :name str))
Run Code Online (Sandbox Code Playgroud)
对于使用以下defn形式定义的函数:
user> (-> #'map meta :name)
map
user> (defn nothing [& _])
#'user/nothing
user> (-> #'nothing meta :name)
nothing
Run Code Online (Sandbox Code Playgroud)
这需要访问var,而不仅仅是var保存的函数值.
编辑:我发现了一种更好的方式 Clojure 包含一个名为 demunge 的函数。因此,与其重新发明轮子,不如直接使用它;)
(clojure.repl/demunge (str map?));; "clojure.core/map?@2b68895c"
Run Code Online (Sandbox Code Playgroud)
或者如果你想要一个美化版
(defn- pretty-demunge
[fn-object]
(let [dem-fn (demunge (str fn-object))
pretty (second (re-find #"(.*?\/.*?)[\-\-|@].*" dem-fn))]
(if pretty pretty dem-fn)))
(pretty-demunge map?);; "clojure.core/map?"
Run Code Online (Sandbox Code Playgroud)
我认为有一种更干净的方法可以做到这一点。我遇到了同样的问题,想知道作为函数参数的函数名称。我无法使用宏,因为我需要映射它,所以这里是我得到的:(假设是字符串?函数是作为参数传递的)
(clojure.string/replace (second (re-find #"^.+\$(.+)\@.+$" (str string?)))
#"\_QMARK\_" "?")
; string?
Run Code Online (Sandbox Code Playgroud)
当然,这不是一个完整的解决方案,但我相信您可以从这里开始。基本上 Clojure 将函数名称修改为可以使用的名称。所以基本的显然是:你需要解开那个!这很容易,因为 str 可用于任何函数 :D ,返回函数的重整名称。
顺便说一句,这也有效
(def foo string?)
(clojure.string/replace (second (re-find #"^.+\$(.+)\@.+$" (str foo)))
#"\_QMARK\_" "?")
; string?
Run Code Online (Sandbox Code Playgroud)
玩得开心
| 归档时间: |
|
| 查看次数: |
5643 次 |
| 最近记录: |