为了更好地理解,我将用一个示例函数来说明:
将其放入上下文中:
user> (defn foo [client-opts
table
& [{:keys [attr-conds
last-prim-kvs
span-reqs
return
limit
total-segments
filter-expr
segment return-cc?]
:as opts
:or {span-reqs {:max 5}}}]]
(println "client-opts")
(clojure.pprint/pprint client-opts)
(println "table")
(clojure.pprint/pprint table)
(println "opts")
(clojure.pprint/pprint opts)
(println "the symbol attr-conds is bound to:" attr-conds)
(println "the symbol limit is bound to:" limit)
(println "the symbol span-reqs is bound to:" span-reqs))
#'user/foo
user> (foo :I'm-a-client-opt
:I'm-a-table
{:attr-conds 1
:span-reqs [1 2 3]
:limit 47}
{:attr-conds :i-will-be-ignored}
{:limit :i-will-also-be-ignored})
client-opts
:I'm-a-client-opt
table
:I'm-a-table
opts
{:attr-conds 1, :span-reqs [1 2 3], :limit 47}
the symbol attr-conds is bound to: 1
the symbol limit is bound to: 47
the symbol span-reqs is bound to: [1 2 3]
nil
现在我们看到它将一些名称绑定到列表中第一个映射的部分,因此让我们拆开这个解构表达式:
&
[
{:keys [attr-conds
last-prim-kvs
span-reqs
return
limit
total-segments
filter-expr
segment return-cc?]
:as opts
:or {span-reqs {:max 5}}}]
因此,在嵌套的解构表达式中,关键字“:or”为符号分配默认值,如果函数的第三个参数是一个映射,并且该映射没有为关键字“:span-reqs”提供值。如果关键字“:span-reqs”存在并包含不提供“:max”值的其他键,则不执行任何操作。在此上下文中,“:or”不会将默认值合并到映射中,仅在完全缺少值时提供值:
以下是完全未指定值的情况:
user> (foo :I'm-a-client-opt
:I'm-a-table
{:attr-conds 1
:limit 47}
{:attr-conds :i-will-be-ignored}
{:limit :i-will-also-be-ignored})
client-opts
:I'm-a-client-opt
table
:I'm-a-table
opts
{:attr-conds 1, :limit 47}
the symbol attr-conds is bound to: 1
the symbol limit is bound to: 47
the symbol span-reqs is bound to: {:max 5}
nil
同时,如果指定的值不包括:max,则再次使用一个值。
user> (foo :I'm-a-client-opt
:I'm-a-table
{:attr-conds 1
:span-reqs {:min -7}
:limit 47}
{:attr-conds :i-will-be-ignored}
{:limit :i-will-also-be-ignored})
client-opts
:I'm-a-client-opt
table
:I'm-a-table
opts
{:attr-conds 1, :span-reqs {:min -7}, :limit 47}
the symbol attr-conds is bound to: 1
the symbol limit is bound to: 47
the symbol span-reqs is bound to: {:min -7}
nil