Aar*_*rup 10 scala compiler-errors
谁能解释下面的编译错误?有趣的是,如果我将方法的返回类型更改get()
为String
,则代码编译得很好.请注意,该thenReturn
方法有两个重载:一元方法和一个至少需要一个参数的varargs方法.在我看来,如果调用在这里是模棱两可的,那么它总是模棱两可的.
更重要的是,有什么方法可以解决歧义吗?
import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito._
trait Thing {
def get(): java.lang.Object
}
new MockitoSugar {
val t = mock[Thing]
when(t.get()).thenReturn("a")
}
Run Code Online (Sandbox Code Playgroud)
错误:对重载定义的模糊引用,两个方法然后返回特征类型
java.lang.Object,java.lang.Object*)org.mockito.stubbing.OngoingStubbing [java.lang.Object]和方法返回特征OngoingStubbing的特征OngoingStubbing type(java.lang.Object)org.mockito.stubbing.OngoingStubbing [java.lang.Object]匹配参数类型(java.lang.String)when(t.get()).thenReturn("a")
Dan*_*ral 10
嗯,这是模棱两可的.我认为Java语义允许它,并且它可能值得一张要求在Scala中应用Java语义的票证.
ambiguitity的来源是这样的:一个vararg参数可以接收任意数量的参数,包括0.所以,当你写的时候thenReturn("a")
,你的意思是调用thenReturn
哪个接收一个参数,或者你的意思是调用thenReturn
它接收一个对象加上一个vararg,将0个参数传递给vararg?
现在,发生了类似的事情,Scala试图找出哪种方法"更具体".任何对细节感兴趣的人都应该在Scala的规范中查找,但这里是对这种特殊情况下发生的事情的解释:
object t {
def f(x: AnyRef) = 1 // A
def f(x: AnyRef, xs: AnyRef*) = 2 // B
}
Run Code Online (Sandbox Code Playgroud)
如果你打电话
f("foo")
,A和B都适用.哪一个更具体?
- 可以使用类型参数调用B
(AnyRef)
,因此A与B一样具体.(AnyRef, Seq[AnyRef])
由于元组转换,可以使用类型参数调用A ,Tuple2[AnyRef, Seq[AnyRef]]
符合AnyRef
.因此B与A一样具体.因为两者都是特定的,所以对f的引用是不明确的.
至于"元组转换"的东西,它是Scala最模糊的语法糖之一.如果您拨打一个电话f(a, b)
,在那里a
和b
有类型A
和B
,并没有f
接受(A, B)
,但有一个f
它接受(Tuple2(A, B))
,则该参数(a, b)
将转换成一个元组.
例如:
scala> def f(t: Tuple2[Int, Int]) = t._1 + t._2
f: (t: (Int, Int))Int
scala> f(1,2)
res0: Int = 3
Run Code Online (Sandbox Code Playgroud)
现在,thenReturn("a")
调用时没有元组转换.那不是问题.问题是,鉴于元组转换是可能的,两个版本都不thenReturn
是更具体,因为传递给一个的任何参数也可以传递给另一个.
小智 7
在Mockito的特定情况下,可以使用为void方法设计的备用API方法:
doReturn("a").when(t).get()
Run Code Online (Sandbox Code Playgroud)
Clunky,但它必须这样做,因为Martin等人似乎不会为了支持Java的varargs而牺牲Scala.
好吧,我想出了如何解决歧义(回想起来似乎有点明显):
when(t.get()).thenReturn("a", Array[Object](): _*)
Run Code Online (Sandbox Code Playgroud)
正如安德烈亚斯所指出的,如果模糊方法需要空引用而不是空数组,则可以使用类似的方法
v.overloadedMethod(arg0, null.asInstanceOf[Array[Object]]: _*)
Run Code Online (Sandbox Code Playgroud)
解决歧义.
归档时间: |
|
查看次数: |
3835 次 |
最近记录: |