考虑这种形式:
(def v [42 "foo" 99.2 [5 12]])
我已经读过,如果我必须以某种形式声明一些未使用的变量,我应该
在这种解构形式let中用 like 来表示它们:_
(let [[x _ _ [y z]] v]
  (+ x y z))
我的问题是分配如何_发生?由于这不会引发异常,我假设第二个_会覆盖第一个,但我不确定。那么这是如何工作的呢?
考虑这种形式:
(def v [42 "foo" 99.2 [5 12]])
我已经读过,如果我必须以某种形式声明一些未使用的变量,我应该
在这种解构形式let中用 like 来表示它们:_
(let [[x _ _ [y z]] v]
  (+ x y z))
我的问题是分配如何_发生?由于这不会引发异常,我假设第二个_会覆盖第一个,但我不确定。那么这是如何工作的呢?
这种使用_纯粹是传统的:从 Clojure 的角度来看,它只是一个可用于命名本地的常规符号。因此,您可以简单地直接检查 的值_以确认您的理解:
(let [[x _ _ [y z]] v]
  _)
;= 99.2
至于幕后发生的事情,最简单的检查方法是宏展开let表单:
(macroexpand-1 '(let [[x _ _ [y z]] v] _))
上面的结果,为了清楚起见重新格式化,如下所示:
(let* [vec__7 v
       x (clojure.core/nth vec__7 0 nil)
       _ (clojure.core/nth vec__7 1 nil)
       _ (clojure.core/nth vec__7 2 nil)
       vec__8 (clojure.core/nth vec__7 3 nil)
       y (clojure.core/nth vec__8 0 nil)
       z (clojure.core/nth vec__8 1 nil)]
  _)
所以第二个_只是掩盖了第一个。
let*是后面的实现细节let;它是编译器直接理解的一种特殊形式,let宏添加了解构支持。