*
正则表达式运算符:检查0个或多个谓词/模式,如下所示:
(s/def ::seq-of-keywords (s/* keyword?))
;; opts are alternating keywords and booleans
(s/def ::opts (s/* (s/cat :opt keyword? :val boolean?)))
(s/conform ::opts [:silent? false :verbose true])
;;=> [{:opt :silent?, :val false} {:opt :verbose, :val true}]
但是据我了解,s/cat
检查一个序列。
所以为什么(s/* (s/cat))
不是要检查每个序列都符合(s/cat)
的序列。
类似这样的东西:
(s/conform ::opts [[:silent? false] [:verbose true]])
为什么它的行为像s/*
flatten
ed s/cat
?或如何检查类似[[:silent? false] [:verbose true]]
的东西?
答案 0 :(得分:1)
您可以使用coll-of
来做到这一点:
(s/conform (s/coll-of ::opts) [[:silent? false] [:verbose true]])
=> [[{:opt :silent?, :val false}] [{:opt :verbose, :val true}]]
有时有助于生成示例数据:
(gen/generate (s/gen ::opts))
=> (:aqfR6b*C/. false :?.03/Vu7? false :Y17UL0/McsI5h true)
与[[:silent? false] [:verbose true]]
的模式不匹配
但这可能应该更接近您要寻找的东西:
(gen/generate (s/gen (s/coll-of (s/tuple keyword? boolean?))))
=> [[:X_o.u?7i/o.dIgTy false] [:L?*/_WY._:z true] [:X26:-j/l2q!u-7I false]]
答案 1 :(得分:0)
为什么...
s/*
变平s/cat
?
...,因为正则表达式是 flat 序列的结构化规范。释义the Spec Guide to Sequences ...
s/spec
的显式调用中。如何指定类似
[[:silent? false] [:verbose true]]
的东西?
要指定成对的序列,每个对都是一个关键字,后跟一个布尔值:
(s/def ::opts (s/* (s/spec (s/cat :opt keyword? :val boolean?))))
请注意,s/spec
包装了s/cat
。现在,例如...
=> (s/conform ::opts [[:silent? false] [:verbose true]])
[{:opt :silent?, :val false} {:opt :verbose, :val true}]
您当然可以像akond一样使用
s/tuple
而不是s/cat
和s/coll-of
而非s/*
,无需插入s/spec
。