You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Clojure.spec定义嵌套序列/向量的规范?

如何用Clojure.spec正确定义嵌套序列/向量的规范

你的问题出在cat的行为上:cat是用来匹配平铺的序列元素,而非嵌套的子序列。当你在内层使用(s/cat :int int?)时,spec会把它当成需要平铺到父序列中的元素规则,所以会尝试把[1]直接匹配int?,导致校验失败。

修复方案

以下几种方式都可以正确定义嵌套序列的规范:

1. 用s/spec包裹内层cat

s/spec会将内层规范包装成一个独立的校验单元,告诉spec这个位置是一个需要整体校验的子序列:

(s/def ::test (s/cat :s any? :r (s/spec (s/cat :int int?))))
(s/explain-str ::test ["test" [1]])
;; 返回空字符串,说明校验通过

2. 直接使用序列类型规范

如果明确知道内层是向量或特定类型的序列,可以用s/vector-of、s/coll-of这类更精准的规范:

;; 匹配包含单个int的向量
(s/def ::test (s/cat :s any? :r (s/vector-of int?)))
(s/explain-str ::test ["test" [1]])
;; 校验通过

;; 匹配包含恰好一个int的任意序列
(s/def ::test (s/cat :s any? :r (s/coll-of int? :count 1)))
(s/explain-str ::test ["test" [1]])
;; 校验通过

3. 用s/and结合序列判断

如果需要更灵活的嵌套结构校验,可以先判断该位置是序列,再应用内层规范:

(s/def ::test (s/cat :s any? :r (s/and sequential? (s/cat :int int?))))
(s/explain-str ::test ["test" [1]])
;; 校验通过

核心逻辑

cat的设计目标是组合多个规范来匹配连续平铺的元素(比如["test" 1]这种结构)。当你需要匹配嵌套的子序列时,必须显式标记该位置是一个独立的子序列单元,通过s/spec或序列类型规范来实现这一点。

内容的提问来源于stack exchange,提问作者Joerg Schmuecker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 09:35:10