如果s/keys
规范未定义任何有效的参数键(:req
、:req-un
、:opt
、:opt-un
、:gen
),则它将无声地进行。
使用req-un
代替:req-un
(符号代替关键字,可能是无意中这样做的)
user> (s/def ::foo (s/or :string string? :number number?))
:user/foo
user> (s/def ::foo-map-broken (s/keys req-un [::foo]))
:user/foo-map-broken
user> (s/conform ::foo-map-broken {:foo []})
{:foo []}
;;arg key can be anything
user> (s/def ::foo-map-broken2 (s/keys 42 [::foo]))
:user/foo-map-broken2
user> (s/conform ::foo-map-broken2 {:foo []})
{:foo []}
我的意见:我倾向于认为对s/keys
的调用应该进行更严格的验证,因此会抛出错误。我能想到的唯一支持当前行为的论点是,s/keys
的参数实际上是一个映射,而映射在Clojure中通常不被视为封闭的。但1>>不进行任何操作的结果似乎仍然值得报错,2>>用户实际上并没有传递一个映射,并且可能没有意识到实现将他们的参数键和参数值转换为一个映射。
(我遇到这种行为时,clj-kondo将我的一个规范标记为错误,我注意到一个像我上面提到的类似的打字错误,其中我使用了req-un
而不是:req-un。我将:req-un改为关键字,这揭示了规范中的错误,但这已经是我几个月没摸代码了,所以我希望早点发现它:--) )