それ以外の
(let [x 1] (my-expression))
私は使用しようとしています:
(let (vector x 1) (my-expression))
理由は聞かないでください。私は通常のブラケットの方が好きです。しかし、Clojure は次のように述べています。
let requires a vector for its binding in ...
どうしたの?
それ以外の
(let [x 1] (my-expression))
私は使用しようとしています:
(let (vector x 1) (my-expression))
理由は聞かないでください。私は通常のブラケットの方が好きです。しかし、Clojure は次のように述べています。
let requires a vector for its binding in ...
どうしたの?
let
(コンパイル時に)バインディング用のベクトルが必要なため、その場所にベクトル関数呼び出しを配置しようとしても機能しません(実行時にのみベクトルが生成されるため)。
ただし、少しのmacro-fuを使用して独自のletを作成できます。
(defmacro mylet [bindings & exprs]
`(let ~(vec bindings) ~@exprs))
(mylet (x 1) (inc x))
=> 2
マクロのソースを見てくださいlet
(defmacro let
"binding => binding-form init-expr
Evaluates the exprs in a lexical context in which the symbols in
the binding-forms are bound to their respective init-exprs or parts
therein."
{:added "1.0", :special-form true, :forms '[(let [bindings*] exprs*)]}
[bindings & body]
(assert-args let
(vector? bindings) "a vector for its binding"
(even? (count bindings)) "an even number of forms in binding vector")
`(let* ~(destructure bindings) ~@body))
bindings
マクロが を介して正しい引数が与えられたことを確認しようとすると、引数が評価されないことに気付くでしょうassert-args
。
clojure が を評価する時点で(vector? bindings)
、最初の要素としてa を含み、その後にその引数が続くbindings
フォーム ( ) であるため、その時点では a ではありません。list
fn
vector
たとえば、このコードは機能します。
(eval `(let ~(vector 'a 1) (println ~'a)))
これは、ベクトルの代わりにリストを受け入れる独自のletマクロを作成できることを意味します。これはClojureの全体的な経験にとってかなり悪いことであり、私はそれをお勧めしません。