2016-11-14 13 views
3

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

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

official advice,按我的理解,是有名的键应该具有相同的语义无处不在。

我该如何解决这个问题?我可以称它们为“红值”和“蓝值”,但这使得代码和标准之间的对应关系不太清晰。我可以把每个结构放在它自己的命名空间吗?

回答

3

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

(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/valid? ::red {:value "foo"}) 
(s/valid? ::blue {:value 100}) 
+0

感谢:

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

您可以用类似的值验证。为了检查我的理解 - ':: red'中的红色与':red/value'中的红色完全无关,不是吗?还有什么方法可以在这里使用命名空间映射,例如'#:: red {:value“hi”...}' –

+1

Re red - yes。命名空间映射语法只是语法,所以'#:: red {:value“hi”}'和'{:: red/value“hi”}'是完全相同的数据。我的意思是,你可以使用,无关紧要,这是完全正交的数据是否符合规范。 –