如何解析Clojure定义中的嵌套参数?

时间:2016-12-07 16:04:44

标签: clojure

我正在浏览一些Clojure source code并遇到了这个功能:

(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以来。

2 个答案:

答案 0 :(得分:3)

<强>校正

正如@Josh指出的那样,顺序解构需要nth才能工作:可选性不够。

这是sequential destructuring的简单案例。让我们使用一个显示正在发生的事情的函数:

(defn foo [app-state [r c]]
 {:app-state app-state, :r r, :c c})
  • 第一个参数app-state可以是任何内容。
  • 第二个参数[r c]必须类似于序列 nth适用于。然后
    • rfirst元素,
    • c是它的第二个。
  • 如果序列不够长,则会产生nil

示例:

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

(foo inc "hello, world!")
;{:app-state #<core$inc clojure.core$inc@32d23c2f>, :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
; ...

答案 1 :(得分:2)

示例中的函数draw-mask有两个参数。第一个是app-state,它不在您的代码中使用,第二个可以是几种不同类型的数据之一:来自地图,字符串,列表或最常见的矢量的值。您可以在此处查看nthFrom(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 中可以使用的不同类型。

这称为顺序clojure code,正如上面提到的其他评论,这是一个很大的话题。但是,对于您的情况,这是它的工作原理:

seqable?

这里有一个澄清:结构是否set不是能够被破坏的主要标准。例如,seqable?nth,但无法进行解构。 顺序 解构的主要标准(不同于关联解构,使用地图,此处未讨论)是必须支持CharSequence。在destructuring中,您将看到可能类型的列表。它们是:RandomAccess,本机Java数组,MatcherMap.EntrySequentialSequential({{1}}将涵盖最常见的结构:列表和矢量)。