2017-03-08 46 views
0

我想根据clojure中的类型获取对象的“默认值”。例如,它可能工作是这样的:在clojure中获取对象类型的“默认值”?

(default-value 15) ;; => 0 
(default-value "hi") ;; => "" 

在这两种情况下,它需要的值的类型,并返回值的类型的“空白”实例。我能想出的最好的是

(defn default-value [x] (.newInstance (.getClass x))) 

但是,这并不对数字工作:

repl=> (.newInstance (.getClass 1)) 

NoSuchMethodException java.lang.Long.<init>() java.lang.Class.getConstructor0 (Class.java:3082) 
+0

数字“默认”值取决于数字的使用方式。例如。 0用于加法,1用于乘法运算。 – ClojureMostly

回答

2

有没有真正的任何这样的事,作为一个“默认值”的类型,除非你是寻找Java默认的方式 - 当你不提供明确的值时,初始化构造函数中的东西。这只是:

  • 布尔=>假
  • 数=> 0
  • 对象=>空

如果你想要一些更复杂(例如,字符串=> “”),你会必须自己编写它,通过以某种方式将对象的类型调度为您控制的代码。

+0

同意 - Clojure没有一个类型的“默认值”的概念,所以它是由你来建立一个条件,如果你想要的东西。 –

3

看起来多方法可能是一个不错的选择:

(defmulti getNominalInstance (fn [obj] (.getClass obj))) 
(defmethod getNominalInstance java.lang.Long [obj] (Long. 0)) 
(defmethod getNominalInstance java.lang.String [obj] "") 

(prn :long (getNominalInstance 5)) 
(prn :string (getNominalInstance "hello")) 

;=> :long 0 
;=> :string "" 

的问题是,长只有2层构造,内搭无论是原始的长或字符串,分别。

Long(long value) - Constructs a newly allocated Long object 
that represents the specified long argument. 

Long(String s) - Constructs a newly allocated Long object 
that represents the long value indicated by the String parameter. 

这是不合法的Java说 “新长征()”,这是什么呢newInstance()。所以,你必须手动使用defmulti或同等产品。

+1

我结束了去这条路线,除了我使用'defprotocol'和'extend-protocol'而不是多方法,因为它们是用于基于单个参数类型的调度情况 – djhaskin987