Clojure:定义的模式中的哈希映射和数组映射类型冲突

时间:2018-02-07 12:55:46

标签: java clojure hashmap compojure

我正在研究Clojure API,但是当地图中的项目数发生变化时,遇到了关于Clojure在HashMapArrayMap之间自动“类型切换”的问题。

阅读文档: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"
}

如文档中所述,如果:bar对象在body中返回少于9个项目,那么它将产生ArrayMap,它可以正常工作。无论如何,当:bar对象缩放并返回超过9个项目时,请求失败,返回错误:

(not (instance? clojure.lang.PersistentArrayMap a-clojure.lang.PersistentHashMap))

因为:bar已自动(神奇地)切换为HashMap

反之亦然,如果我将:bar的架构类型设置为HashMap,那么少于9个项目的对象也不起作用。

无论如何,我们总是可以将类型强制为HashMap

2 个答案:

答案 0 :(得分:2)

这两种类型都太具体了。您应该使用更通用的类型,表示任何类似地图的类型。显而易见的选择是clojure.lang.IPersistentMap

答案 1 :(得分:0)

我假设您使用的是Plumatic Schema

您可以定义一个谓词来捕获所有类型的地图,例如

(ns your.schema.namespace
  (:require [schema.core :as s]))

(def Map (s/pred map?))

(defschema FooSchema
  {:id s/Str
   :bar Map})

map?会在Clojure中为任何类型的地图返回true

=> (map? (array-map))
=> true
=> (map? (hash-map))
=> true
相关问题