2016-12-07 13 views
0

私はいくつかのClojure source codeを閲覧し、この機能に出くわした:Clojureでネストされたパラメータを解析する方法defn?

(defn draw-mask [app-state [r c]] 
    (let [x1 (+ 25 (* c 50)) 
     y1 (+ 25 (* r 50))] 
    [:circle {:cx x1 :cy y1 :r 12 :fill "white"}])) 

私は理解していないこと[app-state [r c]]が解析される方法です。どのような典型的なデータ構造がこれに渡され、どのようにdefnがそれを解釈しますか? clojureのドキュメントでこれに言及していただければ、特にClojureDocs.org was of no help on the subject以降になります。

+0

IIRC、すべての消滅は、 'deconstruct'(またはそのような何か)マクロを使用しています。リストの場合は 'first'、' rest'、 'nth'、そしてマップの場合はアクセサの代理人を呼び出します。ちょうど典型的なマクロ "マジック"。 – Carcigenicate

+1

これは「破壊」です - http://clojure.org/guides/destructuringなどの良い文書を見つけるのに役立ちます。 –

+0

...率直に言って、 (これは私がこれを読んでいる方法です)は、StackOverflowの良い質問になるには余りにも幅があります。上記のリンクを解除したページを見ると、答えが合理的にカバーできる内容よりもはるかに多くのコンテンツがあります。 –

答えて

2

例の関数draw-maskには2つの引数があります。最初はapp-stateで、これはコードでは使用されず、2番目のデータはマップ、文字列、リスト、または最も一般的なベクトルの値のうちのいくつかの異なるタイプのデータの1つです。 clojure codenthFromで使用できるさまざまなタイプがここに表示されます。

これはシーケンシャルdestructuringと呼ばれ、前述の他のコメントと同様に大きな話題です。しかし、あなたのケースのために、これは、それがどのように動作するかです:

(draw-mask xyz [3 9])  ---> In draw-mask, r is 3, and c is 9. 
(draw-mask xyz [3])  ---> In draw-mask, r is 3, and c is nil. 
(draw-mask xyz [3 9 12]) ---> In draw-mask, r is 3, and c is 9 -- 12 is not bound 

ここに一つの明確化:構造がseqable?であるか否かの非構造することができることのための主要な基準ではありません。たとえば、setseqable?ですが、構造化することはできません。 シーケンシャル destructuring(ここでは説明していないマップを使用した連想的な構造解除とは異なります)の主な条件は、nthをサポートする必要があるということです。 RT.javaに、可能なタイプのリストが表示されます。それらは:CharSequence、ネイティブJava配列、MatcherMap.Entry、およびSequentialSequentialはリストとベクトルの最も一般的な構造をカバーします)です。

3

修正

@Joshとしてポイントうち、シーケンシャルな破壊は仕事にnthが必要です。seqabilityは十分ではありません。


これは単純な場合のsequential destructuringです。のは、何が起こっているかを示す機能を使用してみましょう:

(defn foo [app-state [r c]] 
{:app-state app-state, :r r, :c c}) 
  • 最初の引数、app-stateは、何もすることができます。
  • 第2引数の[r c]は、 nthが適用されるシーケンスのようなものでなければなりません。次いで
    • rfirst元素であり、
    • cは秒です。
  • シーケンスが十分でない場合は、nilとなります。

例:

(foo 1()) 
;{:app-state 1, :r nil, :c nil} 

(foo inc "hello, world!") 
;{:app-state #<core$inc [email protected]>, :r \h, :c \e} 

(foo :one [:two :three :four]) 
;{:app-state :one, :r :two, :c :three} 

(foo "Flubalub" (drop 5 (iterate #(* 10 %) 1))) 
;{:app-state "Flubalub", :r 100000, :c 1000000} 

しかし

(foo 99 #{1 2}) 
;java.lang.UnsupportedOperationException: nth not supported on this type: PersistentHashSet 
; ... 
関連する問題