Clojure:定义模式中的哈希映射和数组映射类型冲突
Clojure: hash-map and array-map type conflicts in defined schema
我正在研究 Clojure API,但 运行 关于 Clojure 在 HashMap
和 ArrayMap
之间自动 "type-switching" 的问题里面的地图变化。
阅读文档:https://clojuredocs.org/clojure.core/array-map#example-57392e25e4b071da7d6cfd0c
假设我有一个这样的 POST 请求:
(POST "/" []
:body [foo FooSchema]
(create-response ok {:message "foo!"}))
FooSchema
定义如下:
(def ArrayMap clojure.lang.PersistentArrayMap)
(def Bar ArrayMap)
(s/defschema FooSchema
{:id s/Str
:bar Bar})
:bar
作为具有如下结构的 javascript 对象发送:
{
id: 1,
fh: 1,
rdstr: "flying"
}
如文档中所述,如果 body
中的 :bar
对象 return 少于 9 个项目,那么它会生成 ArrayMap,它工作正常。 Anyway,当:bar
对象缩放和return超过9项时,请求失败,return错误:
(not (instance? clojure.lang.PersistentArrayMap a-clojure.lang.PersistentHashMap))
因为 :bar
自动(神奇地)切换为 HashMap
。
反之亦然,如果我将 :bar
的架构类型设置为 HashMap
,则少于 9 个项目的对象也不起作用。
无论如何我们总是可以强制类型为 HashMap
?
两种类型都太具体了。您应该使用更通用的类型,代表任何类似地图的东西。显而易见的选择是 clojure.lang.IPersistentMap
.
我假设您正在使用 Plumatic Schema。
您可以像这样定义一个谓词来捕获所有类型的地图
(ns your.schema.namespace
(:require [schema.core :as s]))
(def Map (s/pred map?))
(defschema FooSchema
{:id s/Str
:bar Map})
map?
returns true
对于 Clojure 中的任何类型的映射
=> (map? (array-map))
=> true
=> (map? (hash-map))
=> true
我正在研究 Clojure API,但 运行 关于 Clojure 在 HashMap
和 ArrayMap
之间自动 "type-switching" 的问题里面的地图变化。
阅读文档:https://clojuredocs.org/clojure.core/array-map#example-57392e25e4b071da7d6cfd0c
假设我有一个这样的 POST 请求:
(POST "/" []
:body [foo FooSchema]
(create-response ok {:message "foo!"}))
FooSchema
定义如下:
(def ArrayMap clojure.lang.PersistentArrayMap)
(def Bar ArrayMap)
(s/defschema FooSchema
{:id s/Str
:bar Bar})
:bar
作为具有如下结构的 javascript 对象发送:
{
id: 1,
fh: 1,
rdstr: "flying"
}
如文档中所述,如果 body
中的 :bar
对象 return 少于 9 个项目,那么它会生成 ArrayMap,它工作正常。 Anyway,当:bar
对象缩放和return超过9项时,请求失败,return错误:
(not (instance? clojure.lang.PersistentArrayMap a-clojure.lang.PersistentHashMap))
因为 :bar
自动(神奇地)切换为 HashMap
。
反之亦然,如果我将 :bar
的架构类型设置为 HashMap
,则少于 9 个项目的对象也不起作用。
无论如何我们总是可以强制类型为 HashMap
?
两种类型都太具体了。您应该使用更通用的类型,代表任何类似地图的东西。显而易见的选择是 clojure.lang.IPersistentMap
.
我假设您正在使用 Plumatic Schema。
您可以像这样定义一个谓词来捕获所有类型的地图
(ns your.schema.namespace
(:require [schema.core :as s]))
(def Map (s/pred map?))
(defschema FooSchema
{:id s/Str
:bar Map})
map?
returns true
对于 Clojure 中的任何类型的映射
=> (map? (array-map))
=> true
=> (map? (hash-map))
=> true