Как отличить карту Java от карты Clojure?

Допустим, у меня есть следующий код:

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

Мне нужна функция, которая позволит мне обнаруживать карты, пришедшие из Java, например:

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

Что-нибудь из коробки?

2 ответа

Решение

Я бы сделал это:

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 интерфейс, но не являющийся постоянной картой.

Ты можешь использовать map? проверить, реализует ли что-то IPersistentMap что верно для карт Clojure, но не для java.utils.* карты:

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

Чтобы быть более точным, вы должны скорее проверить, соответствует ли данный объект некоторым требованиям (например, является постоянным, неизменным / изменяемым - map? ответит на этот конкретный вопрос). Нет простого способа узнать, есть ли у вас реализация карты на Java, как вы могли бы получить любую другую реализацию из внешней библиотеки, которая может иметь собственную реализацию: java.util.Map или расширение одной из конкретных реализаций из java.util пакет.

Другие вопросы по тегам