想象一下命名空间中有以下require语句:
(ns my.core
(:require '[mylib.sth :as thing]))
(def somevar 123)
是否有办法通过thing
从此命名空间外部访问mylib.sth?我的意思是以某种方式获得与定义somevar相同的行为:
(ns somethingelse)
my.core/somevar
;; =123
(my.core/thing/myf "param") ;; something like this
;; ...
答案 0 :(得分:1)
resolve
和ns-resolve
是针对这种情况制作的。
如果找不到符号,它们将返回nil,否则返回var,你可以deref以获得当前的边界值。
user=> (ns my.test)
nil
my.test=> (def hidden 5)
#'my.test/hidden
my.core=> (ns my.core (:require [my.test :as t]))
nil
my.core=> (in-ns 'user)
#object[clojure.lang.Namespace 0x25930632 "user"]
user=> @(resolve 'my.test/hidden)
5
user=> @(ns-resolve 'my.core 't/hidden)
5
这很有效,但它也是最后的选择。它应该保留用于编写使用命名空间和代码的代码的情况,这些命名空间和绑定在运行时期望在编译时无法访问。例如,在编译可从Java调用的存根时,我使用resolve
来避免项目的传递AOT;存根-main
在运行时调用require
然后调用resolve
,使用已解析的值来访问实际代码。
如果您要查找的只是方便或语法快捷方式,那么更好的选择是如果要使用其值,则明确要求命名空间。