Clojure 为什么在函数中使用*let*?

Clojure 为什么在函数中使用*let*?,clojure,Clojure,我不明白使用let有哪些优点或缺点,因为完全可以避免像下面的代码中那样使用let (defn make-adder [x] (let [y x] (fn [z] (+ y z)))) (def add2 (make-adder 2)) ;; or without let (defn add2 [z] (+ 2 z)) (add2 4) 命名中间结果有三个主要原因: 你想帮助程序员,包括你自己,理解他们到底是什么。 您希望缓存它们,以便它们可以在多个位置使用,而无需再次计算表达

我不明白使用let有哪些优点或缺点,因为完全可以避免像下面的代码中那样使用let

(defn make-adder [x]
  (let [y x]
    (fn [z] (+ y z))))
(def add2 (make-adder 2))

;; or without let
(defn add2 [z] (+ 2 z))

(add2 4) 

命名中间结果有三个主要原因:

你想帮助程序员,包括你自己,理解他们到底是什么。 您希望缓存它们,以便它们可以在多个位置使用,而无需再次计算表达式。如果计算表达式有副作用,并且只希望发生一次,则这一点尤为重要。 您正在创建一个将使用let ed名称但不向外部世界透露的名称。 在makeadder示例中,不需要let,因为它只是为传入参数建立别名。但是,如果你有更多的参与,那么这些优势开始变得相关

就因为我手头有它,这里有一些代码来自:


命名中间结果有三个主要原因:

你想帮助程序员,包括你自己,理解他们到底是什么。 您希望缓存它们,以便它们可以在多个位置使用,而无需再次计算表达式。如果计算表达式有副作用,并且只希望发生一次,则这一点尤为重要。 您正在创建一个将使用let ed名称但不向外部世界透露的名称。 在makeadder示例中,不需要let,因为它只是为传入参数建立别名。但是,如果你有更多的参与,那么这些优势开始变得相关

就因为我手头有它,这里有一些代码来自:


问题不在于是否使用let,而在于是否直接定义add2函数或使用函数生成函数makeadder来生成它

你的函数生成函数是

(defn make-adder [x]
  (let [y x]
    (fn [z] (+ y z))))
如前所述,let在这里没有任何用处,最好省略它,给予

(defn make-adder [x]
  (fn [z] (+ x z)))
。。。这更容易阅读。我们可以看到,给定一个数字,它将返回一个函数,该函数将该数字添加到它显示的任何内容中:

((make-adder 2) 4)
;6
给makeadder2起一个名字只是让人困惑

显式定义它时,添加2的无名函数是

将其应用于4:


问题不在于是否使用let,而在于是否直接定义add2函数或使用函数生成函数makeadder来生成它

你的函数生成函数是

(defn make-adder [x]
  (let [y x]
    (fn [z] (+ y z))))
如前所述,let在这里没有任何用处,最好省略它,给予

(defn make-adder [x]
  (fn [z] (+ x z)))
。。。这更容易阅读。我们可以看到,给定一个数字,它将返回一个函数,该函数将该数字添加到它显示的任何内容中:

((make-adder 2) 4)
;6
给makeadder2起一个名字只是让人困惑

显式定义它时,添加2的无名函数是

将其应用于4:


在大多数编程语言中,您可以声明和使用局部变量,以帮助您设计函数或方法体。在Clojure中,允许您将本地符号绑定到任何可以生成值、数据结构或其他本地函数定义的表达式

您的示例非常简单,不需要let构造,但很快您就会遇到这样的情况,它将对函数逻辑的可读性有很大帮助

let也是一种分解代码的方法,它通过只计算一次表达式并在多个地方使用结果来提高可读性和性能


最后但并非最不重要的一点是,当表达式返回集合等复合结构时,让我们非常方便地生成简洁的代码。

在大多数编程语言中,您可以声明和使用局部变量,以帮助您设计函数或方法体。在Clojure中,允许您将本地符号绑定到任何可以生成值、数据结构或其他本地函数定义的表达式

您的示例非常简单,不需要let构造,但很快您就会遇到这样的情况,它将对函数逻辑的可读性有很大帮助

let也是一种分解代码的方法,它通过只计算一次表达式并在多个地方使用结果来提高可读性和性能


最后但并非最不重要的一点是,当表达式返回复合结构(如集合)时,let可以非常方便地生成简洁的代码。

这里有两件事要做——一个生成函数的函数,也使用let。最后一个例子将两者都去掉了。这里有两件事要做——一个生成函数的函数,还使用let。最后一个示例将两者都去掉。