首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >clojure.spec:‘for’vs‘for’用于序列规范

clojure.spec:‘for’vs‘for’用于序列规范
EN

Stack Overflow用户
提问于 2016-06-02 05:54:20
回答 2查看 2.3K关注 0票数 19

我正在遵循clojure.spec的指南(http://clojure.org/guides/spec)。我对altor在序列规范方面的不同感到困惑。

对我来说,以下两个例子同样适用。那这两者有什么区别?

代码语言:javascript
复制
; 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])
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-02 10:28:52

s/alt用于连接嵌套regex规范,其中使用s/or指定嵌套序列。在您的示例中,这没有什么区别,因为您没有使用嵌套正则规范。下面是一个示例:

代码语言:javascript
复制
(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指定了相反的内容:

代码语言:javascript
复制
(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
票数 14
EN

Stack Overflow用户

发布于 2016-08-02 12:34:38

http://clojure.org/guides/spec,我们知道

当regex操作组合在一起时,它们描述了一个序列。

这意味着,如果要使嵌套序列有效,就应该这样做。

代码语言:javascript
复制
(s/def ::config (s/* 
                 (s/cat :prop string?
                        :val (s/spec
                              (s/alt :s string? :b #(instance? Boolean %))))))

然后您的数据看起来是这样的(注意到方括号周围的)

代码语言:javascript
复制
(s/explain ::config ["-server" ["foo"] "-verbose" [true] "-user" [13]])

另外,如果你这么做了。

代码语言:javascript
复制
(s/def ::config (s/* (s/cat :prop string?
                            :val (s/spec 
                                  (s/or :s string? :b #(instance? Boolean %))))))

您的数据应该与旧的数据相同(注意到周围没有括号)

代码语言:javascript
复制
(s/explain ::config ["-server" "foo" "-verbose" true "-user" 13])

顺便说一下,对于非嵌套序列。(s/alt )和(s/或)之间仍然有一点差别:

代码语言:javascript
复制
;;; 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]
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37583708

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档