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

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 根据字段指定子贴图的内容_Clojure_Clojure.spec - Fatal编程技术网

Clojure 根据字段指定子贴图的内容

Clojure 根据字段指定子贴图的内容,clojure,clojure.spec,Clojure,Clojure.spec,也许我的问题已经得到了回答,但我仍然坚持使用submap规范 想象一下,我有两种可能性 {:type :a :spec {:name "a"}} {:type :b :spec {:id "b"}} 简而言之::spec键取决于类型。对于类型:a,:spec必须包含字段:name,对于类型:b而言,spec必须包含字段:id 我试过这个: (s/def ::type keyword?) (defmulti input-type ::type) (defmethod input-type

也许我的问题已经得到了回答,但我仍然坚持使用submap规范

想象一下,我有两种可能性

{:type :a
 :spec {:name "a"}}

{:type :b
 :spec {:id "b"}}
简而言之:
:spec
键取决于类型。对于类型
:a
:spec
必须包含字段
:name
,对于类型
:b
而言,spec必须包含字段
:id

我试过这个:

(s/def ::type keyword?)

(defmulti input-type ::type)
(defmethod input-type :a
  [_]
  (s/keys :req-un [::name]))
(defmethod input-type :b
  [_]
  (s/keys :req-un [::id]))
(s/def ::spec (s/multi input-type ::type))

(s/def ::input (s/keys :req-un [::type ::spec]))
这告诉我:没有方法([:spec nil])。 我想我明白了原因:也许类型是不可访问的。 所以我想制作一个更高级别的多规格(基于整个地图)

问题:我不知道如何根据
:type
定义
:spec
,因为它们的名称相同。你知道怎么做吗

谢谢

为了适应
:spec
映射的两种不同含义,我们可以在不同的名称空间中定义它们:
:id/spec
:name/spec
。请注意,这些关键字的非命名空间后缀都是
spec
,而我们的
keys
规范使用的是未命名的关键字。这里这些是“假”名称空间,但您也可以在项目中的其他“真”名称空间中定义它们

(defmulti input-type :type)
(defmethod input-type :a [_]
  (s/keys :req-un [::type :name/spec]))
(defmethod input-type :b [_]
  (s/keys :req-un [::type :id/spec]))

(s/def ::input (s/multi-spec input-type :type))

(s/valid? ::input {:type :a, :spec {:name "a"}})
=> true
您还可以获取此规范的样本:

(gen/sample (s/gen ::input))
=>
({:type :a, :spec {:name ""}}
 {:type :b, :spec {:id "aI"}} ...
为了适应
:spec
映射的两种不同含义,我们可以在不同的名称空间中定义它们:
:id/spec
:name/spec
。请注意,这些关键字的非命名空间后缀都是
spec
,而我们的
keys
规范使用的是未命名的关键字。这里这些是“假”名称空间,但您也可以在项目中的其他“真”名称空间中定义它们

(defmulti input-type :type)
(defmethod input-type :a [_]
  (s/keys :req-un [::type :name/spec]))
(defmethod input-type :b [_]
  (s/keys :req-un [::type :id/spec]))

(s/def ::input (s/multi-spec input-type :type))

(s/valid? ::input {:type :a, :spec {:name "a"}})
=> true
您还可以获取此规范的样本:

(gen/sample (s/gen ::input))
=>
({:type :a, :spec {:name ""}}
 {:type :b, :spec {:id "aI"}} ...