2016-04-29 18 views
0

オーバーロードされた複数のメソッドがデフォルトのパラメータを持つことができないのはなぜですか(あいまいでない場合)、さらに重要なことは、その制限の回避策が考えられる場合です。オーバーロードされたメソッドのデフォルトの引数

ここにいくつかの背景があります。私は、プリミティブ型と参照を区別するためにこのトリックを使用しています:

def toJson[T](writer: Writer, data: T)(implicit ev: T <:< AnyVal = null) { 
    val wrapped = (Option(ev), data) match { 
    case (Some(_), _) | (_, _:String) => Map("result" -> data) 
    case _ => data 
    } 
    jsonMapper.writeValue(writer, data) 
} 

Tがプリミティブ型、evがnullではない、と私は有効なJSONを生成するためにMapにデータをラップすることができますだけではなく、プリントアウトされると生の価値 これは動作しますが、問題はこの機能のさまざまな味が必要であるということです。たとえば:オーバーロード関数がすべてではないが、何らかの理由でデフォルト引数を持つことができるので、

def toJson[T](out: OutputStream, data: T)(implicit ev: T <:< AnyVal = null) = 
    toJson(new OutputStreamWriter(out), data) 
def toJson(data: T)(implicit ev: T <:< AnyVal = null) = { 
    val w = new StringWriter 
    toJson(w, data) 
    w.toString 
} 

等... 残念ながら、これは、コンパイルされません。なぜこれが許されないのかという正当な理由は考えられず、そのような制限の根拠については興味があります。もっと重要なのは、私が上で述べたように、誰かが私がここでやろうとしていることを別の方法で勧めることができれば(1つの機能に15の異なる意味のある名前をつけること以外に)、アドバイスに感謝します。その後

import scala.reflect._ 
def isPrimitive[T:ClassTag] = implicitly[ClassTag[T]].erasure.isPrimitive 

def toJson[T:ClassTag](writer: Writer, data: T) { 
    val wrapped = if (isPrimitive[T]) Map("result" -> data) else data 
    jsonMapper.writeValue(writer, wrapped) 
} 

デフォルト値はありませんので、オーバーロードすると問題なく最も簡単な代替の

+0

https://groups.google.com/forum/#!msg/scala-user/FyQK3-cqfaY/fXLHr8QsW_0J –

答えて

2

一つは、このヘルパーメソッドを使用することです。

このソリューションでは、元のコードとはわずかに異なるセマンティクスがありますが、注意してください。上記のコードでは、 "プリミティブ"は実際にはJVMの意味でプリミティブを意味します(https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.3参照)。一方、コードでは値クラス(JVM仕様に従って非プリミティブ型をラップする値クラスでさえも)は "プリミティブ"と見なされます。

+0

ありがとうございます。私はそれをコンパイルするためにマイナーな編集をしましたが、全体的には良いアイデアのように見えます。なぜ私は自分自身について考えていないのか分かりません... – Dima

+0

ちょっとした注意: 'scala.reflect._'をインポートするとそのままコンパイルされます(パッケージに' ClassTag'タイプとルックアップを実行する 'classTag'メソッド)。それはタイプミスではありませんでした:-) –

+0

ああ、知っておいて、ありがとう、ありがとう。申し訳ありません – Dima

関連する問題