1

次のフォームを検討してください。

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

未使用の変数をフォームで宣言する必要がある場合は、次のような構造化フォームでletそれらを示す必要があることを読みました。_

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

私の質問は、への割り当てがどのように行われる_かです。これは例外をスローしないので、2番目_が最初のものをオーバーライドすると思いますが、よくわかりません。では、これはどのように機能するのでしょうか。

4

1 に答える 1

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)]
  _)

したがって、2 番目_は単純に最初のものをシャドウします。

let*の背後にある実装の詳細letです。これは、letマクロが分解サポートを追加するコンパイラによって直接認識される特別な形式です。

于 2013-08-15T18:07:58.107 に答える