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 修复为关键词,这样就可以发现规格中的错误,但是这段代码已经几个月未触及,所以我希望能 sooner :--))