这是一个错误吗?尝试从包含 nil 的 s/or 规范生成时出现 NullPointerException

Is this a bug? NullPointerException when trying to generate from s/or spec which includes nil

我找到了一种通过使用 s/or 规范生成值来抛出 NullPointerExceptions 的方法。我希望能够生成并标记一个 nil 值,没有 s/nilable 不合适。

这是 clojure.spec 中的错误吗?

(ns blah
  (:require [clojure.spec.alpha :as s])) 

(s/def ::fine (s/or :int int? :nil nil?)
(s/def ::throws (s/or :int (s/int-in 1 5) :zero zero? :nil nil?)

(s/exercise ::fine)
=>
([nil [:nil nil]
 [-1 [:int -1]]
 [nil [:nil nil]]
 [0 [:int 0]]
 [nil [:nil nil]]
 [15 [:int 15]]
 [-25 [:int -25]]
 [nil [:nil nil]]
 [-2 [:int -2]]
 [-30 [:int -30]]])]])

(s/exercise ::throws)
=>
NullPointerException   clojure.lang.Numbers.ops (Numbers.java:1018)

如果您限制 ::throws 的执行次数,您会看到正确的 :int:zero 值,抛出的是 :nil

这个有效:

(s/def ::works (s/or :int (s/int-in 1 5) :nil nil? :zero zero?))

我假设规范会尝试按照 or 备选方案的顺序进行调整。使用 zero? 谓词符合 nil 会崩溃,但在其前面移动 nil? 将防止这种情况发生。

同样有效的是使用集合而不是谓词:

(s/def ::throws (s/or :int (s/int-in 1 5) :zero #{0} :nil nil?))