Clojure 这是虫子吗?试图从包含nil的s/或规范生成时发生NullPointerException

Clojure 这是虫子吗?试图从包含nil的s/或规范生成时发生NullPointerException,clojure,nullpointerexception,clojure.spec,Clojure,Nullpointerexception,Clojure.spec,我找到了一种通过使用s/or规范生成值来抛出NullPointerException的方法。我希望能够生成并标记nil值,没有s/nilable不合适 这是clojure.spec中的错误吗 (ns废话 (:要求[clojure.spec.alpha:as s])) (s/def::罚款(s/or:int?:nil-nil?) (s/def::throws(s/or:int(15中的s/int):零零?:nil-nil?) (s/练习:罚款) => ([nil[:nil-nil] [-1[:in

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

这是
clojure.spec
中的错误吗

(ns废话
(:要求[clojure.spec.alpha:as s]))
(s/def::罚款(s/or:int?:nil-nil?)
(s/def::throws(s/or:int(15中的s/int):零零?:nil-nil?)
(s/练习:罚款)
=>
([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/练习::投掷)
=>
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?))
我假设spec将尝试按照
备选方案的顺序进行一致性。使用
zero?
谓词一致性
nil
将崩溃,但在前面移动
nil?
将阻止这种情况发生

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

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

(zero?nil)
抛出npe。我能够让它使用
:zero(0 1中的s/int)
工作,但了解问题发生的原因仍然很有趣。Oops忘记了测试该顺序,谢谢!我应该尝试向docstring提交补丁吗?使用集合谓词
:zero{0}
而不是
:zero zero?
也可以工作。我同意它会抛出,因为
zero?
在conform期间使用(有效)nil输入调用。与
(s/conform zero?nil)
相同。谢谢Taylor,使用了{0}现在进入最后一部分。@JeremyField我想这里要强调的是,并不是所有谓词都同样适用于spec。
zero?
,比如
奇数?
偶数?
,是需要有效数字输入的谓词之一(可能是出于性能原因),并且需要额外的
int?
检查才能在规范中安全使用。这与可以处理任何类型输入的谓词(如
nil?
int?
简单关键字?
)形成对比。