数字?不能在规范中使用
number? can't be used in spec
在 Clojure 1.9.0-alpha13 中,我可以使用 spec/and
和 integer?
而不是 and
和 number?
来定义规范谓词,它出现了。这令人费解。同样令人费解的是,当我定义谓词时没有错误,但只有当我尝试使用它来定义规范时才会出现错误。
user=> (use '[clojure.spec :as s])
...
nil
user=> (s/def pos-int? (s/and integer? pos?))
user/pos-int?
user=> (s/def ::foo pos-int?)
:user/foo
user=> (s/def pos-num? (s/and number? pos?))
user/pos-num?
user=> (s/def ::bar pos-num?)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: pos-num? ...
为什么我在第二种情况下会出错,而在第一种情况下却不会?这是一项涉及我不知道的区别的功能,还是一个错误?
注意我直接定义::bar
不会报错:
user=> (s/def ::bar (s/and number? pos?))
:user/bar
我相信您已经发现了与来自 clojure.core
的预定义 pos-int?
的交互。源代码中:
src/clj/clojure/core.clj 第 1400 行
(defn pos-int?
"Return true if x is a positive fixed precision integer"
{:added "1.9"}
[x] (and (int? x)
(pos? x)))
没有pos-num?
存在。
您的代码不正确。 s/def
应使用限定关键字调用以注册规范,而不是符号。
所以这个:
user=> (s/def pos-int? (s/and integer? pos?))
user/pos-int?
并没有按照您的想法行事。它实际上是在符号 user/pos-int?
.
下注册一个函数定义(您通常通过 s/fdef
进行)
user=> (s/def ::foo pos-int?)
:user/foo
这是可行的,因为 pos-int?
是 clojure.core 中的一个现有函数(也就是说,它根本没有使用您之前的定义)。
这似乎也有效,但同样不正确:
user=> (s/def pos-num? (s/and number? pos?))
user/pos-num?
这失败了:
user=> (s/def ::bar pos-num?)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: pos-num? ...
因为 pos-num 不是 现有谓词。
假设您想注册两个正整数和数字规范,您可以这样做:
(s/def ::pos-int (s/and integer? pos?))
(s/def ::pos-num (s/and number? pos?))
在 Clojure 1.9.0-alpha13 中,我可以使用 spec/and
和 integer?
而不是 and
和 number?
来定义规范谓词,它出现了。这令人费解。同样令人费解的是,当我定义谓词时没有错误,但只有当我尝试使用它来定义规范时才会出现错误。
user=> (use '[clojure.spec :as s])
...
nil
user=> (s/def pos-int? (s/and integer? pos?))
user/pos-int?
user=> (s/def ::foo pos-int?)
:user/foo
user=> (s/def pos-num? (s/and number? pos?))
user/pos-num?
user=> (s/def ::bar pos-num?)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: pos-num? ...
为什么我在第二种情况下会出错,而在第一种情况下却不会?这是一项涉及我不知道的区别的功能,还是一个错误?
注意我直接定义::bar
不会报错:
user=> (s/def ::bar (s/and number? pos?))
:user/bar
我相信您已经发现了与来自 clojure.core
的预定义 pos-int?
的交互。源代码中:
src/clj/clojure/core.clj 第 1400 行
(defn pos-int?
"Return true if x is a positive fixed precision integer"
{:added "1.9"}
[x] (and (int? x)
(pos? x)))
没有pos-num?
存在。
您的代码不正确。 s/def
应使用限定关键字调用以注册规范,而不是符号。
所以这个:
user=> (s/def pos-int? (s/and integer? pos?))
user/pos-int?
并没有按照您的想法行事。它实际上是在符号 user/pos-int?
.
s/fdef
进行)
user=> (s/def ::foo pos-int?)
:user/foo
这是可行的,因为 pos-int?
是 clojure.core 中的一个现有函数(也就是说,它根本没有使用您之前的定义)。
这似乎也有效,但同样不正确:
user=> (s/def pos-num? (s/and number? pos?))
user/pos-num?
这失败了:
user=> (s/def ::bar pos-num?)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: pos-num? ...
因为 pos-num 不是 现有谓词。
假设您想注册两个正整数和数字规范,您可以这样做:
(s/def ::pos-int (s/and integer? pos?))
(s/def ::pos-num (s/and number? pos?))