Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Clojure中的函数/宏中的另一个命名空间中定义变量?_Clojure_Namespaces - Fatal编程技术网

如何在Clojure中的函数/宏中的另一个命名空间中定义变量?

如何在Clojure中的函数/宏中的另一个命名空间中定义变量?,clojure,namespaces,Clojure,Namespaces,我正在Clojure中试用ns,以下是我的尝试: user=> (in-ns 'some-ns) #<Namespace some-ns> some-ns=> (def aa 100) #'some-ns/aa some-ns=> (in-ns 'user) #<Namespace user> user=> (= some-ns/aa 100) true user=> (= user/aa 100) CompilerException jav

我正在Clojure中试用
ns
,以下是我的尝试:

user=> (in-ns 'some-ns)
#<Namespace some-ns>
some-ns=> (def aa 100)
#'some-ns/aa
some-ns=> (in-ns 'user)
#<Namespace user>
user=> (= some-ns/aa 100)
true
user=> (= user/aa 100)
CompilerException java.lang.RuntimeException: No such var: user/aa, compiling:(NO_SOURCE_PATH:5:1) ;this works as expected
user=> (defn function [] (in-ns 'some-other-ns) (def cc 100) (in-ns 'user))
#'user/function
user=> (function)
#<Namespace user>
user=> (= some-other-ns/cc 100)
CompilerException java.lang.RuntimeException: No such var: some-other-ns/cc, compiling:(NO_SOURCE_PATH:8:1)
user=> (= user/cc 100)
true

创建并插入或定位一个全局变量,该变量的名称为symbol,命名空间的值为当前命名空间(*ns*)

我错过了什么

另外,我知道我可以使用
(intern'some ns'a 100)
,但我真正想要的是一个通用函数/宏

(with-ns 'some-ns (def a 100))
(= some/a 100)

intern
是正确的解决方案,您可以在自己的任何函数/宏中使用它。(函数可以调用
intern
;宏可以扩展为代码调用
intern

def
只能直接在顶级表单中使用,或嵌套在顶级表单中,在顶级表单创建后立即执行。因此,
let
中的
def
可以,而函数中的
def
则不行

def
接受编译器的特殊处理,因为
def
表单定义的变量在
def
编译后立即实际创建;但是,当控制流实际到达
def
表单时,将安装
def
表单中指定的初始绑定。这解释了
绑定
示例不起作用的原因——计算的是
*ns*
的编译时值,而此
绑定
表单引入的绑定将在运行时生效

最后,如果您绝对坚持在运行时使用
def
表单来创建Vars,那么方法是使用
eval

(binding [*ns* some-ns]
  (eval '(def foo 1)))

;; some-ns/foo comes into existence with a root binding of 1

请注意,这里的
def
确实发生在顶层,并将在编译后立即执行。

在这个答案中,我将跳过关于
eval
的高运行成本的标准注释。我不建议使用此选项,但这将起作用:
(do(在ns'some-a-ns中)(def dd 100))
-将
dd
定义为
some-a-ns/dd
(binding [*ns* some-ns]
  (eval '(def foo 1)))

;; some-ns/foo comes into existence with a root binding of 1