如何在使用“apply”时显式指定命名空间上的函数在Clojure? [英] How do you explicitly specify a namespace when using "apply" on a function in Clojure?
问题描述
这里的graph是返回在其范围内设置了config的函数的高阶函数:
.neo4jserver.graph)
(defn out1
test func只返回out1。
[config]
out1)
(defn graph
[config]
(fn [func& args]
(apply func config args)))
您创建一个graph实例,然后可以用于调用其他函数并自动传递配置参数:
(def g(graph {:root-urihttp:// localhost}))
(g out1)
; ; => out1
但是,如果你需要/ import图形到另一个命名空间,那么你必须在每个函数调用的前面加上图命名空间:
ns bulbs.neo4jserver.junk
(:require [bulbs.neo4jserver.graph:as graph]))
(def g(graph / graph {:root-urihttp:// localhost}))
;;宁愿做(g out1)
(g graph / out1)
在 apply
函数中显式指定命名空间,以便用户不必:
(defn graph
[config]
(fn [func& args]
;;不知何故在这里指定图形命名空间
(apply func config args) )
最好的方法是什么?
(defn graph
[config]
(fn [func& args]
(apply-ns-resolve'bulbs.neo4jserver .graph func)config args)))
并且呼叫:
(ns bulbs.neo4jserver.junk
(:require [bulbs.neo4jserver.graph:as graph]))
(def g(graph / graph {:root-urihttp:// localhost}))
(g'out1)
但 g
不再是高阶函数。它采用符号,而不是函数。我个人不喜欢这种方法。为什么不喜欢指定命名空间?也许你可以用宏来做你需要的,但我不知道宏。
编辑
不要这样做。使用@Ankur和@Gert在注释中解释的常规函数。
Here "graph" is higher-order function that returns a function with config set in its scope:
(ns bulbs.neo4jserver.graph)
(defn out1
"Test func that simply returns out1."
[config]
"out1")
(defn graph
[config]
(fn [func & args]
(apply func config args)))
You create an instance of graph, which can then be used to call other functions and automatically pass in the config arg:
(def g (graph {:root-uri "http://localhost"}))
(g out1)
;; => "out1"
This works; however, if you require/import graph into another namespace, then you have to prefix each function call with the graph namespace:
(ns bulbs.neo4jserver.junk
(:require [bulbs.neo4jserver.graph :as graph]))
(def g (graph/graph {:root-uri "http://localhost"}))
;; would rather do (g out1)
(g graph/out1)
Instead, I want to explicitly specify the namespace in the apply
function so that users don't have to:
(defn graph
[config]
(fn [func & args]
;; somehow specify the graph namespace here
(apply func config args)))
What's the best way to do this?
You can pass symbol instead of function and resolve it in graph
function:
(defn graph
[config]
(fn [func & args]
(apply (ns-resolve 'bulbs.neo4jserver.graph func) config args)))
And call it:
(ns bulbs.neo4jserver.junk
(:require [bulbs.neo4jserver.graph :as graph]))
(def g (graph/graph {:root-uri "http://localhost"}))
(g 'out1)
But g
is not an high-order function any more. It takes symbol, not function. Personally I don't like this approach. Why don't you like specifying namespace? May be you can do what you need with macro too, but I don't know macros well.
EDIT
Don't do it. Use regular functions as explained by @Ankur and @Gert in comments.
这篇关于如何在使用“apply”时显式指定命名空间上的函数在Clojure?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!