我正在遵循clojure.spec的指南(http://clojure.org/guides/spec)。我对alt和or在序列规范方面的不同感到困惑。
对我来说,以下两个例子同样适用。那这两者有什么区别?
; Use `alt`
(s/def ::config (s/* (s/cat :prop string?
:val (s/alt :s string? :b boolean?))))
(s/explain ::config ["-server" "foo" "-verbose" true "-user" 13])
; Use `or`
(s/def ::config (s/* (s/cat :prop string?
:val (s/or :s string? :b boolean?))))
(s/explain ::config ["-server" "foo" "-verbose" true "-user" 13])发布于 2016-06-02 10:28:52
s/alt用于连接嵌套regex规范,其中使用s/or指定嵌套序列。在您的示例中,这没有什么区别,因为您没有使用嵌套正则规范。下面是一个示例:
(s/def ::number-regex (s/* number?))
(s/def ::or-example (s/cat :nums (s/or :numbers ::number-regex)))
(s/valid? ::or-example [1 2 3])
;;-> false
(s/valid? ::or-example [[1 2 3]])
;;-> true如您所见,or指定了一个嵌套序列,其中启动了一个新的regex上下文,而alt指定了相反的内容:
(s/def ::alt-example (s/cat :nums (s/alt :numbers ::number-regex)))
(s/valid? ::alt-example [1 2 3])
;;-> true
(s/valid? ::alt-example [[1 2 3]])
;;-> false发布于 2016-08-02 12:34:38
从http://clojure.org/guides/spec,我们知道
当regex操作组合在一起时,它们描述了一个序列。
这意味着,如果要使嵌套序列有效,就应该这样做。
(s/def ::config (s/*
(s/cat :prop string?
:val (s/spec
(s/alt :s string? :b #(instance? Boolean %))))))然后您的数据看起来是这样的(注意到方括号周围的)
(s/explain ::config ["-server" ["foo"] "-verbose" [true] "-user" [13]])另外,如果你这么做了。
(s/def ::config (s/* (s/cat :prop string?
:val (s/spec
(s/or :s string? :b #(instance? Boolean %))))))您的数据应该与旧的数据相同(注意到周围没有括号)
(s/explain ::config ["-server" "foo" "-verbose" true "-user" 13])顺便说一下,对于非嵌套序列。(s/alt )和(s/或)之间仍然有一点差别:
;;; for (s/or)
(s/def ::name-or-id (s/or :name string?
:id int?))
(s/conform ::name-or-id 42) ;;=> [:id 42]
;;; for (s/alt)
(s/def ::name-or-id (s/alt :name string?
:id int?))
(s/conform ::name-or-id [42]) ;;=> [:id 42]https://stackoverflow.com/questions/37583708
复制相似问题