我正在尝试在Clojure中创建一个函数,它是(let ...)函数体的本地函数.我尝试了以下内容,但(defn ...)定义了全局命名空间中的内容.
(let [] (defn power [base exp]
(if (= exp 0)
1
(if (> exp 0)
; Exponent greater than 0
(* base (power base (- exp 1)))
; Exponent less than 0
(/ (power base (+ exp 1)) base))))
(println (power -2 3)))
; Function call outside of let body
(println (power -2 3))
Run Code Online (Sandbox Code Playgroud)
现在,我也尝试过:
(let [power (fn [base exp]
(if (= exp 0)
1
(if (> exp 0)
; Exponent greater than 0
(* base (power base (- exp 1)))
; Exponent less than 0
(/ (power base (+ exp 1)) base))))]
(println (power -2 3)))
; Function call outside of let body
(println (power -2 3))
Run Code Online (Sandbox Code Playgroud)
但后来我得到了错误:
Exception in thread "main" java.lang.Exception: Unable to resolve symbol: power in this context (math.clj:6)
Run Code Online (Sandbox Code Playgroud)
如何创建一个函数,其命名空间是let body的本地,并且可以递归调用自身?
Mic*_*ent 10
为此您可以使用letfn:
(letfn [(power [base exp]
(cond
(= exp 0)
1
(> exp 0) ; Exponent greater than 0
(* base (power base (dec exp)))
:else ; Exponent less than 0
(/ (power base (inc exp)) base)))]
(print (power -2 3)))
Run Code Online (Sandbox Code Playgroud)
请注意,我还将嵌套的if-construction更改为cond,我认为它更具可读性.我也分别将(+ exp 1)和( - exp 1)改为(inc exp)和(dec exp).您甚至可以使用recur和accumulator参数来改进函数,但这可能超出了您的问题的范围.另见Brian Carper的评论如下.