我是clojure的新手,我试图尽可能多地理解,但文档太模糊了
当你有一个功能
(fn [_ {:keys [kind]}] kind)
我的理解是该函数采用矢量图,但只想访问第二个参数指定的键,对{:keys.....
吗?
那么我要传递多少个参数给这个函数呢?1 还是 2?
它是一个向量吗?{:kind 1 :dog 2} 还是向量键值 (:kind {....})?
您的函数需要两个参数(具有 arity 2)。第一个参数的名称是_
(下划线),通常表示未使用的变量。(它是一个有效的变量名,它被绑定了,但按照惯例,它不被使用,所以它表示一个占位符。)
第二个参数是解构的 - {:keys [kind]}
,这意味着期望值是一个映射,并且作为解构的结果,一个名为的变量kind
将绑定到:kind
实际参数的键值(如果没有这样的键,则为 nil。)
所以你的函数需要两个参数,第一个被忽略,第二个必须是一个带有键的映射:kind
(也许其他键也是如此,但它们被忽略了。)
((fn [_ {:keys [kind]}] kind) :foo {:kind :bar, :color :green})
=> :bar
PS我又看了你的问题,我意识到你的困惑可能来自哪里。语法[_ {:kind [kind]}]
看起来像一个向量,在第二个位置包含一个地图。这是正确的,但在 Clojure 中并非所有地方都使用向量表示法意味着您可以将向量粘贴到那里。Clojure 用户为函数的形式参数列表使用方括号 - 这是 Clojure 中常见模式的一部分,即在可能需要序列的任何地方都使用向量文字。与其他需要在许多地方小心使用引号以避免将列表解释为函数应用程序表单的 Lisp 相比,它实际上非常方便。但这是题外话,重要的一点是在fn
(和defn
)方括号中表示参数列表,并不意味着参数是向量。
让我们给函数起一个名字:
(defn splot [_ {:keys [kind]}] kind)
这是简写
(defn splot [_ {kind :kind}] kind)
两个(位置)参数的函数:
_
,通常未使用,并且:kind
条目绑定到 local kind
;然后返回绑定到的任何内容kind
。
失败的绑定返回nil
。
举些例子:
(splot "..." 6) ;nil
(splot "..." {}) ;nil
(splot "..." {:kind 77}) ;77
通过在 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 []}
解构语法进行了非常全面的描述,并描述了绑定来自 hashmap 的值的简写。在 Clojure中是一个 hashmap,并且是一个向量,它们是不可互换的。调用以查找 in 中的键下的值。并且是等价的。{}
[]
(:foo m)
get
:foo
m
(let [{:keys [foo]} {:foo "bar"}] ...)
(let [foo (:foo {:foo "bar"})] ...)