在玩Clojure时我写了一个函数,它依赖于someSymbol在第一次运行时未定义,因为(resolve someSymbol)
将返回nil。事实证明,通过defn
在其中的def
处使用函数会导致符号被定义:
(resolve 'someSymbol)
(defn resolvePokus []
(prn "I was evaluated")
(def someSymbol 1)
)
(resolve 'someSymbol)
在REPL中产生:
nil
#'user/resolvePokus
#'user/someSymbol
这是否意味着,在运行defn
时会评估一些特殊表达式?哪个?
简要介绍一下defn的来源并没有向我透露任何内容,除了这个核心功能中有一个TODO评论:)
答案 0 :(得分:1)
我假设你在repl中运行。我没有看到你描述的行为:
clj.core=> (resolve 'someSymbol)
nil
clj.core=> (defn resolvePokus []
#_=> (prn "I was evaluated")
#_=> (def someSymbol 1)
#_=> )
#'clj.core/resolvePokus
clj.core=> (resolve 'someSymbol)
#'clj.core/someSymbol
; try to use it -> error "Unbound..."
clj.core=> someSymbol
#object[clojure.lang.Var$Unbound 0x542f6481 "Unbound: #'clj.core/someSymbol"]
clj.core=> (resolvePokus) ; run the function
"I was evaluated"
#'clj.core/someSymbol
clj.core=> (resolve 'someSymbol) ; still can resolve
#'clj.core/someSymbol
clj.core=> someSymbol ; now we can use it
1
clj.core=> (declare xyz) ; creates a var, but unbound
#'clj.core/xyz
clj.core=> (resolve 'xyz) ; we can see resolve it
#'clj.core/xyz
clj.core=> xyz ; try to use it -> error "Unbound"
#object[clojure.lang.Var$Unbound 0x2d1d436f "Unbound: #'clj.core/xyz"]
clj.core=> (def xyz 5) ; define it
#'clj.core/xyz
clj.core=> (resolve 'xyz) ; still can resolve
#'clj.core/xyz
clj.core=> xyz ; now we can use it
5
因此,当我定义函数时,在键入最后的括号后,repl打印出#'clj.core/resolvePokus
已定义但不是someSymbol
。最终的resolve
来电仍会返回nil
。
但是,如果你进一步阅读,那么当Clojure第一次看到(declare someSymbol)
时,它似乎相当于(def someSymbol 1)
。当我手动(declare xyz)
并稍后通过(def xyz 5)
您可能希望look at this answer.详细信息涉及“隐藏”变量及其如何是符号xyz
和值5
之间的匿名中介。
P.S。上面的例子是在Ubuntu 16.04,Clojure 1.8,Java 1.8
上运行的