Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure:如何在Java类上切换大小写_Java_Clojure - Fatal编程技术网

Clojure:如何在Java类上切换大小写

Clojure:如何在Java类上切换大小写,java,clojure,Java,Clojure,我在clojure中有一个java类,它来自一个返回类的方法。我想打开这些,如下所示: (case type java.lang.String (println "Found String" name) java.lang.Long (println "Found Long" name) java.nio.ByteBuffer (println "Found ByteBuffe

我在clojure中有一个java类,它来自一个返回类的方法。我想打开这些,如下所示:

            (case type
                java.lang.String (println "Found String" name)
                java.lang.Long (println "Found Long" name)
                java.nio.ByteBuffer (println "Found ByteBuffer" name)
                java.lang.Boolean (println "Found Boolean" name)
                java.math.BigDecimal (println "Found BigDecimal" name)
                java.lang.Double (println "Found Double" name)
                java.lang.Float (println "Found Float" name)
                java.net.InetAddress (println "Found InetAddress" name)
                java.lang.Integer (println "Found Integer" name)
                java.util.Date (println "Found Date" name)
                java.util.UUID (println "Found UUID" name)
                java.math.BigInteger (println "Found BigInteger" name)
                java.util.List (println "Found List" name)
                java.util.Set (println "Found Set" name)
                java.util.Map (println "Found Map" name))
但当我运行这个时,我得到了

 java.lang.IllegalArgumentException: No matching clause: class java.util.UUID

这是在找不到匹配的案例时抛出的内容。如何匹配case子句中的类?

使用映射而不是
case
表单:

def case-map
  {java.util.Set "Set",
   java.math.BigInteger "BigInteger",
   java.lang.Double "Double",
   java.math.BigDecimal "BigDecimal",
   java.util.List "List",
   java.lang.Float "Float",
   java.util.UUID "UUID",
   java.lang.String "String",
   java.lang.Integer "Integer",
   java.nio.ByteBuffer "ByteBuffer",
   java.lang.Boolean "Boolean",
   java.net.InetAddress "InetAddress",
   java.util.Date "Date",
   java.util.Map "Map",
   java.lang.Long "Long"})

(defn what-is [x] (str (case-map (type x)) " " x))
例如:

(what-is (java.util.Date.))
"Date Mon Sep 22 08:17:55 BST 2014"

(what-is (java.util.UUID. 0 0))
"UUID 00000000-0000-0000-0000-000000000000"


编辑:反对AOT编译中的警告似乎也适用于此解决方案

以下是如何绕过这个问题:

=> (map #(case (class %)
           #=java.lang.String (str "Found String " %)
           #=java.lang.Long (str "Found Long " %))
     ["a" 42])
("Found String a" "Found Long 42")

但是,由于类没有稳定的哈希代码,所以千万不要在AOT编译的代码上使用它。

你真的不能比它做得更好,它基本上是重复调用
实例?
,如下所示:

(condp instance? x
  String :string
  Integer :int
  :unknown)

如果您不想注意子类型,并且只对x的类型使用精确匹配,您可以使用
(condp=(class x)…)

我最终使用了多方法

(defmulti get-row-data-for-class (fn [type-class name row] type-class))
(defmethod get-row-data-for-class java.lang.Boolean [type-class name row] (.getBool row name))
(defmethod get-row-data-for-class java.lang.Double [type-class name row] (.getDouble row name))
(defmethod get-row-data-for-class java.lang.Float [type-class name row] (.getFloat row name))
然后像

(let [data (get-row-data-for-class type-class name row)])

对两三年前的
#=…
状态提出疑问。而且还没有记录在案。使用它安全吗?@Thumbnail No.不要使用它。如果在函数内部而不是外部构建映射,则可以避免AOT编译问题。当然,你要付出一次又一次的建造成本。哇,我真的建议你一次又一次地建造这张地图吗?解决AOT的一个更好的方法是定义映射的延迟,而不是映射本身,以便在您第一次使用它时构建它,而不是在编译时或反复使用它:
(def case map(delay{…}))(defn what is[x](get@case map(class x))
很高兴知道这不应该起作用。但也许它隐藏在答案中,是什么原因使它不能像预期的那样工作?