4

我正在使用 Clojure 来实现(书面)标准文档。总的来说,我对 Clojure 允许我编写符合标准不同部分的代码的方式感到满意。着眼于未来,我正在尝试clojure.spec为它写一个。在文档中,他们定义了具有命名字段的各种结构化数据元素。然而,不同结构中的字段具有相同的名称,例如“red”结构有一个“value”字段,它是一个字符串,但“blue”结构有一个“value”字段,它是一个整数。在编写规范时我该如何处理?

(s/def ::value ???)
(s/def ::red (s/keys :req [::value ...]))
(s/def ::blue (s/keys :req [::value ...]))

据我了解,官方建议是命名键在任何地方都应该具有相同的语义。

我应该如何处理这个?我可以称它们为“红色值”和“蓝色值”,但这使得代码和标准之间的对应关系不太清楚。我可以将每个结构都放在自己的命名空间中吗?

4

1 回答 1

4

您的示例为所有规范名称使用当前名称空间,但您应该利用名称空间来消除名称的歧义。

(s/def ::red (s/keys :req [:red/value ...]))
(s/def ::blue (s/keys :req [:blue/value ...]))

您可以将这些规格与地图一起使用,例如:

(s/valid? ::red {:red/value "foo"})
(s/valid? ::blue {:blue/value 100})

此外,s/keys支持:req-un将命名规范链接到非限定属性名称的选项,如果这是您必须使用的。

(s/def ::red (s/keys :req-un [:red/value ...]))
(s/def ::blue (s/keys :req-un [:blue/value ...]))

您可以使用以下值进行验证:

(s/valid? ::red {:value "foo"})
(s/valid? ::blue {:value 100})
于 2016-11-14T15:07:41.797 回答