如何区分 java 地图和 clojure 地图?

How to distinguish java map from clojure map?

假设我有以下代码:

(def m1 (java.util.HashMap.))
(def m2 (java.util.LinkedHashMap.))
(def m3 {})

我需要一个函数来检测来自 java 的地图,例如:

(map java-map? [m1 m2 m3]) ;; => (true true false)

有开箱即用的东西吗?

您可以使用 map? 检查某些东西是否实现了 IPersistentMap,这对 Clojure 映射是正确的,但对 java.utils.* 映射不是:

(map? (java.util.HashMap.)) ;; => false
(map? (java.util.LinkedHashMap.)) ;; => false
(map? {}) ;; => true

更准确地说,您应该检查给定对象是否满足某些要求(例如,持久性,immutable/mutable - map? 将回答该特定问题)。没有简单的方法来判断您是否获得了地图的 Java 实现,因为您可以从外部库获得任何其他实现,这些实现可能具有 java.util.Map 的自定义实现或扩展其中一个具体实现java.util 包。

我会这样做:

user=> (defn java-map? [m] 
         (and (instance? java.util.Map m) 
              (not (map? m))))
#'user/java-map?

user=> (java-map? {})
false

user=> (java-map? (java.util.HashMap.))
true

user=> (java-map? [])
false

因此您只需检查它是否实现了核心 java 的 Map 接口,而不是 clojure 的持久映射。