2016-04-29 66 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不是空的,我可以把数据封装成Map出示有效的JSON,而不是仅仅打印出原始价值。 这有效,但问题是我需要有不同的功能。例如:

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 
} 

等等 不幸的是,这并不能编译,因为重载函数不能都出于某种原因默认参数。我想不出有什么理由不允许这么做,并且对这种限制的理由感到好奇。更重要的是,正如我上面所说,如果有人可以推荐另一种方法做什么,我想在这里做(除了想出一个函数的15个不同但有意义的名称等),我会很感激的建议。

+0

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

回答

2

最简单的一种替代的办法是使用这个helper方法:

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) 
} 

没有缺省值,所以超载没有问题。

请注意,此解决方案与您的原始代码具有稍微不同的语义。与上面的代码,“原始”的真正含义在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