2017-03-08 2 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がデフォルトでコンストラクタ内の要素を初期化する方法を探します。それはちょうどです:

  • ブール=> falseを
  • 番号=> 0
  • オブジェクト=> nullの

あなたが(例えば、文字列=> "")より洗練された何かをしたい場合は、あなたがします何らかの形でオブジェクトの型を制御するコードにディスパッチすることによって、自分で書き込む必要があります。

(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つのコンストラクタを持っているということです。

+0

合意 - Clojureには型の "デフォルト値"の概念がありません。したがって、必要に応じて何かを作成する条件を作成するのはあなた次第です。 –

3

はマルチメソッドはぴったりかもしれないように見えます。

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. 

それはnewInstance()が何をするかである "新しいロング()" を、言うために正当なJavaではありません。したがって、defmultiまたは同等のものを使用して手動で行う必要があります。

+1

私はこのルートに行きましたが、マルチメソッドの代わりに 'defprotocol'と' extend-protocol'を使用した点を除いて、このような単一引数型のディスパッチケースのためのものです – djhaskin987

関連する問題