object List {
def apply[T](): List[T] = new Nil
def apply[T](x1: T): List[T] = new Cons(x1, new Nil)
def apply[T](x1: T, x2: T): List[T] = new Cons(x1, new Cons(x2, new Nil))
def apply[T](elems: T*): List[T] =
elems.foldRight(List[T])((elem, l) => new Cons(elem, l))
}
List(1) // Error - Ambiguity
List('a', 'b') // Works fine
scalac抱怨第一个实例化(对重载定义的引用不明确),因为单个参数和varargs方法都是相同特定的。
搜索stackoverflow时,我发现强制使用单参数方法是可能的。列表[Int](1)
将使编译器使用def apply[T](x1:T)
。
我的问题是为什么第二个实例化匹配def applice[T](x1:T,x2:T)
而没有额外的“提示”?换句话说,为什么双参数方法比varargs方法更具体,而单参数方法不是?
为了回答您的问题,我们需要看看Scala编译器必须执行重载解析时会发生什么。SLS 6.23.3(用于Scala 2.9)中对此进行了描述。
让我们举一个稍微简单一点的例子:
object Test {
def apply[T](x1: T) = "one arg" // A
def apply[T](x1: T, x2: T) = "two args" // B
def apply[T](elems: T*) = "var-args: " + elems.size // C
}
看看这三个电话:
Test(1) // fails, ambiguous reference, A and C both match arguments
Test[Int](1) // returns "one arg"
Test(1,2) // returns "two args", not "var-args: 2"
然后编译器计算每个备选方案的相对权重
。SLS规定
备选方案A相对于备选方案B的相对权重是从0到2的一个数字,定义为
在这一点上,必须有一个选项比所有其他选项得分更高,否则就有歧义错误。我们可以忽略“已定义”的部分,它们是在同一个地方定义的。
这也解释了为什么test[Int](1)
成功调用one参数版本。最后两个替代方案是相同的,但是A
的类型参数已经绑定到int
,类型推断不能再更改它以适应C
的参数。
最后,应用相同的逻辑可以说明为什么test(1,2)
工作良好:
b
与c
一样具体:您始终可以使用b
的参数调用c
,C
不如B
:再多的类型推断也无法将一个seq
放入接受两个参数的方法中。所以apply[T](x1:T,x2:T)
是最具体的,没有错误。
基本上,为了让var-arg和普通方法产生歧义,它们需要有相同数量的参数,以及在(至少)最后一个参数上欺骗类型推断的方法:
def apply[T](x1: T)
def apply[T](x: T*)
或
def apply[T](x1: Int, x2:T)
def apply[T](x1: Int, x: T*)
我试图使用mockito在scala中模拟,如下所示 会有什么问题?
我最近开始学习Scala和Play框架,在阅读Play框架的Anorm文档时,我得到了以下代码片段: 却被编译错误卡住了:
给定下面用Mockito模拟Scala类的代码,我会得到一个错误并且无法编译: 错误是: 对重载定义的引用不明确,类型为(x$1:class[common.testeable],x$2:org.Mockito.mocksettings)的对象Mockito中的方法mock和类型为(x$1:class[common.testeable],x$2:org.Mockito.stubbing.answhe
我在swagger 2.0文件中定义了两个可重用参数: 然后在我的路由定义中(在本例中为GET),我尝试这样引用这两个: 如果我使用一个$ref,它似乎工作正常(没有编译错误),但是如果我尝试两个都使用,它会看着我: 此外,如果我在查询字符串中传递这些参数并输出<code>req.swagger。params</code>,我得到一个空对象。我做错了什么? 这是规范的完整SSCCE,生成相同的错误
我有一个非常奇怪的问题,很简单,但我不明白问题是什么。 我有一个类,ClassA调用ClassB中的函数,比如- 类A是在我的applicationContext中定义的bean。类xml ClassB中的函数定义看起来像 IntelliJ没有指出任何语法问题,一切看起来都很正常。。。然而,当我试图编译时,Maven出现了一个异常 B类与a类位于不同的模块中,因此B类位于a类的pom中。作为依赖项
为什么我有这个错误? 错误:(5,18)对重载定义的引用不明确,类型为(x$1:String)布尔的类String中的方法startsWith和类型为(x$1:String,x$2:Int)布尔的类String中的方法startsWith匹配预期的类型?水果过滤器(_.startswith==“AP”) 水果过滤器(_.startswith==“AP”)