这种解构如何形成工作?

时间:2013-08-15 17:34:46

标签: clojure destructuring

请考虑以下形式:

(def v [42 "foo" 99.2 [5 12]])

我已经读过,如果我必须以let形式声明一些未使用的变量,我应该用_表示它们 就像在这种解构形式中一样:

(let [[x _ _ [y z]] v]
  (+ x y z))

我的问题是_的作业是如何发生的?由于这不会引发异常,我假设第二个_会覆盖第一个但我不确定。那怎么办呢?

1 个答案:

答案 0 :(得分:6)

_的这种使用纯粹是传统的:从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)]
  _)

所以第二个_只会影响第一个。{/ p>

let*let背后的实施细节;它是编译器直接理解的特殊形式,let宏添加了解构支持。