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



我找到了一种通过使用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?))

最新更新