I believe case
treats the class names as literal symbols - it does not resolve them to actual classes:
>>> (case 'clojure.lang.PersistentArrayMap clojure.lang.PersistentArrayMap 1 17)
1
>>> (case clojure.lang.PersistentArrayMap clojure.lang.PersistentArrayMap 1 17)
17
This is rather unintuitive, but so it works in Clojure's case
. Anyway, the idiomatic way is to use defmulti
and defmethod
instead of switching on type
:
(defmulti encoded-msg class)
(defmethod encoded-msg java.util.Map [x] 5)
(defmethod encoded-msg java.lang.Double [x] 7)
>>> (encoded-msg {})
5
>>> (encoded-msg 2.0)
7
The dispatcher uses the isa?
predicate which deals well with the comparisons of types, in particular it works well with Java inheritance.
If you don't want to use defmulti
, then condp
might replace case
in your use case, as it properly evaluates the test-expressions. On the other hand it doesn't provide constant time dispatch.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…