Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
clojure.spec:`alt`vs`或`for sequence spec_Clojure - Fatal编程技术网

clojure.spec:`alt`vs`或`for sequence spec

clojure.spec:`alt`vs`或`for sequence spec,clojure,Clojure,我正在遵循clojure.spec的指南()。我对序列规范的alt和或之间的差异感到困惑 对我来说,以下两个例子同样有效。那么这两者之间有什么区别呢 ; Use `alt` (s/def ::config (s/* (s/cat :prop string? :val (s/alt :s string? :b boolean?)))) (s/explain ::config ["-server" "foo" "-verbose" true "-use

我正在遵循clojure.spec的指南()。我对序列规范的
alt
之间的差异感到困惑

对我来说,以下两个例子同样有效。那么这两者之间有什么区别呢

; 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])

s/alt
用于连接嵌套的正则表达式规范,其中使用
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
如您所见,
指定了一个嵌套序列,在该序列中新的正则表达式上下文被启动,而
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
从那时起,我们知道

当组合正则表达式操作时,它们描述单个序列

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

(s/def ::config (s/* 
                 (s/cat :prop string?
                        :val (s/spec
                              (s/alt :s string? :b #(instance? Boolean %))))))
然后您的数据如下所示(注意括号)

此外,如果您这样做(s/or)

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


顺便说一句,对于非嵌套序列。(s/alt)和(s/or)之间仍然有一点不同:


尝试一件事:使用
编写规范,然后将其交给
规范/练习
它将为您生成/验证10个示例。然后切换到
alt
并执行相同的操作。我一直在使用
spec/exercise
调试规范,将我认为应该验证的内容与bug规范生成的输出进行比较是非常棒的。我认为这个词是“子序列”,如果我正确理解维基百科的话,子序列的意思正好相反@事件将其更改为嵌套顺序
(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])
;;; 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]