class - 带类的Clojure案例陈述

标签 class clojure switch-statement

我想打开给定对象的类以对其进行编码。

(defn encoded-msg-for [msg]
  (case (class msg)
    java.lang.Double   (encode-double msg)
    java.lang.String   (encode-str msg)
    java.lang.Long   (encode-int msg)
    java.lang.Boolean  (encode-bool msg)
    clojure.lang.PersistentArrayMap (encode-hash msg)
    clojure.lang.PersistentVector (encode-vec msg)
    nil "~"
  )
 )

当我调用(encoded-msg-for {})时,它返回No matching clause: class clojure.lang.PersistentArrayMap
奇怪的是,将案例放入哈希图中(类作为键,字符串作为值)非常好。

另外,(= (class {}) clojure.lang.PersistentArrayMap)为true。这里发生了什么比较,如何切换对象本身的类或(更好)其层次结构中的某个对象?

最佳答案

我相信case将类名视为文字符号-不会将它们解析为实际的类:

>>> (case 'clojure.lang.PersistentArrayMap clojure.lang.PersistentArrayMap 1 17)
1

>>> (case clojure.lang.PersistentArrayMap clojure.lang.PersistentArrayMap 1 17)
17

这相当不直观,但是可以在Clojure的case中使用。无论如何,惯用的方法是使用defmultidefmethod而不是打开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

调度程序使用isa?谓词,该谓词可以很好地处理类型比较,尤其是可以与Java继承一起很好地工作。

如果您不想使用defmulti,那么condp可能会在您的用例中替换case,因为它可以正确评估测试表达式。另一方面,它不提供恒定的时间分配。

关于class - 带类的Clojure案例陈述,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12028944/

相关文章:

java - 禁止在 Eclipse 中登录 clojure?

algorithm - Clojure 奎尔 : nested loops while drawing lines

java - 如何将对象的一个​​元素转换为实例数组?

functional-programming - 使用 Clojure 初始化 JTable 的所有元素的最佳方法是什么?

java - 为什么在 Java 中的方法调用中间使用括号?

C++:在开关中调用类函数

c++ - 是否使用 if (0) 跳过应该工作的开关中的案例?

c++ - Switch case 语句如何在内部实现或工作?

c++ - c++中所有函数的 undefined reference

c - 如何区分重载函数的指针?