在Clojure REPL中:
user> (defn add [x y] (def foo :defined-inside) (+ x y))
#'user/add
user> foo
#object[clojure.lang.Var$Unbound 0x63a0ad69 "Unbound: #'user/foo"]
user> (add 1 1)
2
user> foo
:defined-inside
显然,我认为foo
不应该在add
之外访问,为什么Clojure允许这样做,这与其他lisp(例如。scheme)不同?
答案 0 :(得分:2)
def
在Clojure中总是全局的,与其他一些Lisps不同。
要在函数中创建局部符号绑定,请使用let
。
答案 1 :(得分:0)
在Clojure中,您可以使用let
来定义本地易记:
(defn add [x y]
(let [foo :defined-inside]
(+ x y)))
它甚至可以用于本地功能:
(defn add [x y]
(let [foo (fn [x y] (+ x y))]
(foo x y)))
但是对于相互递归函数,您需要使用letfn
:
(defn is-odd? [n]
(letfn [(is-even? [n]
(if (zero? n)
true
(is-odd? (dec n))))
(is-odd? [n]
(if (zero? n)
false
(is-even? (dec n))))]
(is-odd? n)))
答案 2 :(得分:0)
当我想通过调用函数在全局var lazily 中创建一个绑定时,函数内部的Def很有用。
(defn initialize-browser []
(def browser (run-browser)))
例如,我使用此模式使用selenium运行浏览器。 我可以轻松控制浏览器的状态。 如果我不想运行浏览器,我不会调用该函数。当我想运行和处理浏览器时,我只调用此函数一次,并由其他函数处理。