在Scala中,为什么会允许这种重载?
class log {
def LogInfo(m: String, properties: Map[String, String]): Unit = {
println(m)
}
def LogInfo(m: String, properties: Map[String, String], c: UUID = null): Unit = {
println(m + c.toString())
}
}
在LogInfo函数的第二个定义中,我将extra参数设置为默认值null。当我进行以下调用时,它将调用第一个重载。
val l: log = new log()
val props: Map[String, String] = Map("a" -> "1")
l.LogInfo("message", props)
为什么不抛出异常?使用默认值,我认为两个定义看起来都一样。
答案 0 :(得分:1)
由于编译器选择第一个重载作为适用的重载,因此不会抛出异常。这与the way overload resolution works with default arguments有关。根据规范,对这种方法被丢弃的强烈暗示将是以下几行:
否则,让CC成为适用的替代方案的集合,它不会将应用程序中的任何默认参数用于
e1,…,em
。
这与Scala编译器为这两种方法发出JVM字节代码的方式有关。如果我们编译它们并在窗帘后面看,我们会看到(为了简洁省略实际的字节代码):
public class testing.ReadingFile$log$1 {
public void LogInfo(java.lang.String,
scala.collection.immutable.Map<java.lang.String, java.lang.String>);
Code:
public void LogInfo(java.lang.String,
scala.collection.immutable.Map<java.lang.String, java.lang.String>,
java.util.UUID);
Code:
public java.util.UUID LogInfo$default$3();
Code:
0: aconst_null
1: areturn
}
你看到生成的代码实际上发出了两个方法,一个采用两个参数,一个采用三个。另外,编译器添加了一个名为LogInfo$default$3
的附加方法(该名称实际上具有含义,其中$3
表示&#34;第三个参数的默认参数),它返回{的默认值{1}}第二个重载的变量。如果要调用具有默认参数的方法,则c
将用于引入具有给定值的新变量。
答案 1 :(得分:0)
这两种方法都适用,但重载分辨率特别会抛弃需要默认args的应用程序:
不使用任何默认参数的适用替代方案
http://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#overloading-resolution
对于“为什么”,假设重载有许多默认参数,这样它的大多数应用程序看起来都不像第一种方法的调用。