1

私はclojureが初めてで、できるだけ理解しようとしていますが、ドキュメントは非常に曖昧です

機能があるとき

(fn [_ {:keys [kind]}] kind)

私の理解では、関数はベクトルマップを受け取りますが、2番目のパラメーターで指定されたキーへのアクセスのみが{:keys.....必要です。正しいですか?

では、この関数にいくつのパラメーターを渡せばよいでしょうか? 1つか2つ?

ベクトルですか?{:kind 1 :dog 2} またはベクトル キー値 (:kind {....})?

4

3 に答える 3

2

関数は 2 つのパラメーターを必要とします (アリティ 2 を持ちます)。最初のパラメーターの名前は_(アンダースコア) で、これは通常、使用されない変数を示します。(これは有効な変数名であり、バインドされますが、慣例により使用されないため、プレースホルダーを示します。)

2 番目のパラメーターは destructured -{:keys [kind]}です。これは、期待される値がマップであることを意味し、名前付きの変数を分解した結果、実際のパラメーターのキーの値 (または、そのようなキーがない場合は nil)kindにバインドされます。:kind

したがって、関数は 2 つのパラメーターを想定しています。最初のパラメーターは無視され、2 番目のパラメーターはキーを持つマップでなければなりません:kind(他のキーも同様ですが、無視されます)。

((fn [_ {:keys [kind]}] kind) :foo {:kind :bar, :color :green})
=> :bar

PS私はあなたの質問をもう一度見て、あなたの混乱がどこから来ているのかを理解しました. 構文[_ {:kind [kind]}]は、2 番目の位置にマップを含むベクトルのように見えます。その通りですが、Clojure のどこにでもベクトル表記があるとは限りません。Clojure は、関数の仮パラメーターのリストに角括弧を使用します。これは、シーケンスが予想されるあらゆる場所でベクトル リテラルを使用するという Clojure の一般的なパターンの一部です。リストを関数適用形式として解釈することを避けるために、多くの場所で慎重に引用符を使用する必要がある他の Lisp と比較して、実際には非常に便利です。しかし、それは余談です。重要な点はfn(およびdefn) にあります。角括弧はパラメーター リストを示し、パラメーターがベクトルであることを意味するものではありません。

于 2016-07-27T05:18:30.107 に答える
0

関数に名前を付けましょう。

(defn splot [_ {:keys [kind]}] kind)

これは

(defn splot [_ {kind :kind}] kind)
  • 2 つの (位置) 引数の関数:

    1. _、従来未使用、および
    2. :kindエントリが local にバインドされている匿名マップkind
  • にバインドされているものは何でも返しますkind

失敗したバインディングは を返しnilます。

例えば:

(splot "..." 6)            ;nil
(splot "..." {})           ;nil
(splot "..." {:kind 77})   ;77
于 2016-07-27T09:54:52.410 に答える
-1

repl で試して、特定の関数構文が何をするかを確認するのはかなり簡単です。

+user=> ((fn [_ {:keys [kind]}] kind) (:kind {}))
ArityException Wrong number of args (1) passed to: user/eval1/fn--3  clojure.lang.AFn.throwArity (AFn.java:429)
+user=> ((fn [_ {:keys [kind]}] kind) nil (:kind {}))
nil
+user=> ((fn [_ {:keys [kind]}] kind) nil {:kind 1})
1

{:keys []}分解構文は、公式ドキュメントでかなり包括的に説明されており、ハッシュマップから取得した値をバインドするための省略形について説明しています。Clojure{}では、 はハッシュマップであり[]、ベクトルであり、これらは交換可能ではありません。(:foo m)を呼び出しgetて、キー:fooinの下の値を検索しますm(let [{:keys [foo]} {:foo "bar"}] ...)(let [foo (:foo {:foo "bar"})] ...)同等です。

于 2016-07-27T05:10:03.063 に答える