【发布时间】:2017-04-18 01:47:56
【问题描述】:
在玩 Clojure 时,我编写了一个函数,它依赖于 someSymbol 在第一次运行时未定义,因为 (resolve someSymbol) 将返回 nil。事实证明,defn-ing 函数与 def 在其中某处导致符号被定义:
(resolve 'someSymbol)
(defn resolvePokus []
(prn "I was evaluated")
(def someSymbol 1)
)
(resolve 'someSymbol)
在 REPL 产量中:
nil
#'user/resolvePokus
#'user/someSymbol
这是否意味着在运行defn 时会评估一些特殊表达式?哪个?
简要查看 defn 的源代码并没有向我透露任何信息,除了这个核心函数中有一条 TODO 注释:)
【问题讨论】:
-
非常清楚,顺便说一下,从函数内部重新绑定 Var 的根值是一种非常严重的代码气味。 (也就是说——这不是你应该要做的事情。
-
此外,您实际上可能会查看
someSymbol解析为什么——您会注意到,当它解析时,它是未绑定的——未绑定到 1——直到函数真正叫. -
@AlanThompson,明确记录了它们不同的并发语义。 Re-
def-ing 一个 var 是一个潜在的阻塞操作。 -
@AlanThompson, ...另外,与
alter-var-root不同,def不提供原子性保证。见stackoverflow.com/questions/16447621/… -
仅供参考 - 输入 REPL 时将函数编译为字节码。编译器interns vars it encounters in def expressions in during compile time.
标签: clojure