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 为什么defn似乎在函数体中计算(def符号)?_Clojure - Fatal编程技术网

Clojure 为什么defn似乎在函数体中计算(def符号)?

Clojure 为什么defn似乎在函数体中计算(def符号)?,clojure,Clojure,在玩弄Clojure时,我编写了一个函数,该函数依赖于在第一次运行时未定义someSymbol,因为resolve someSymbol将返回nil。事实证明,通过定义函数中某处的def,可以定义符号: (resolve 'someSymbol) (defn resolvePokus [] (prn "I was evaluated") (def someSymbol 1) ) (resolve 'someSymbol) 在REPL中,收益率: nil #'user/r

在玩弄Clojure时,我编写了一个函数,该函数依赖于在第一次运行时未定义someSymbol,因为resolve someSymbol将返回nil。事实证明,通过定义函数中某处的def,可以定义符号:

 (resolve 'someSymbol)
 (defn resolvePokus []
   (prn "I was evaluated")
   (def someSymbol 1)
   )
 (resolve 'someSymbol)
在REPL中,收益率:

nil
#'user/resolvePokus
#'user/someSymbol
这是否意味着在运行defn时会对某些特殊表达式求值?哪一个


对defn的源代码的简要调查并没有向我透露任何信息,除了在这个核心函数中有一条TODO注释:

我假设您正在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似乎在第一次看到def someSymbol 1时就相当于声明了someSymbol。当我手动声明xyz并稍后通过def xyz 5给它一个值时,您可以看到相同的行为

您可能希望了解隐藏变量的详细信息,以及它如何作为符号xyz和值5之间的匿名中介


另外,上面的例子是在Ubuntu 16.04、Clojure 1.8、Java 1.8上运行的,对不起,我错过了粘贴-最后一行是someSymb而不是someSymbol。正在修正中…你确定最终解决仍然返回零吗?我的REPL不这么认为:user=>resolve'someSymbol nil user=>defn resolvePokus[]\u=>prn我被评估了=>def someSymbol 1\u=>user/resolvePokus user=>resolve'someSymb nil user=>resolve'someSymbol'user/someSymbol user=>resolve'someSymbol'用户/someSymbol仔细阅读并可能刷新页面。resolve'someSymbol除第一次外不返回nil。但是,当defn resolvePokus。。。完成了。我完成了,第一个解析确实像预期的那样返回零。现在我明白了,在defn中,只发生了一些必要符号的声明,但在基础var中没有存储任何值,最终的解析在符号仍然未绑定时确认符号的存在。正当感谢您和Charles D.Time说得很清楚,顺便说一下,从函数内部重新绑定Var的根值是一种非常严重的代码味道。这就是说-这不是你应该做的事情。另外,你可能会看到someSymbol解析为什么-你会注意到,当它解析时,它是未绑定的-不绑定到1-直到函数被实际调用为止。@AlanThompson,它们所不同的并发语义被显式地记录下来。重新定义一个var可能是一个阻塞操作。@AlanThompson,……此外,与altervar root不同,def不提供原子性保证。请参见FYI-输入REPL时,将函数编译为字节码。编译器。