隐式转换为值的错误消息 类

error messages on implicit conversion to value classes

定义一个接受类型的方法:List[_ <: AnyVal]

def foo(x : List[_ <: AnyVal]) = x 

尝试使用 AnyRef:

foo(List(new Test))

error: type mismatch;
 found   : Test
 required: AnyVal
Note that implicit conversions are not applicable because they are ambiguous:
 both method ArrowAssoc in object Predef of type [A](self: A)ArrowAssoc[A]
 and method Ensuring in object Predef of type [A](self: A)Ensuring[A]
 are possible conversion functions from Test to AnyVal

问题1:在警告信息中,为什么编译器会忽略Predef.scala中定义的另外两个"generic to AnyVal"隐式转换?

final implicit class StringFormat[A] extends AnyVal
final implicit class any2stringadd[A] extends AnyVal

消除之前的歧义并强制编译器使用 ArrowAssoc 隐式转换:

foo(List(new Test -> 1))

error: the result type of an implicit conversion must be more specific than AnyVal

问题2:这个错误提示是什么意思?令人困惑。 ArrowAssoc中的方法def -> [B](y: B): Tuple2[A, B] = Tuple2(self, y) class returns 一个AnyRef类型的Tuple2。因此,更有用的错误消息可能是 found Tuple2 required AnyVal?

先回答你的第二个问题。试试这个:

class Temp

implicit class Arrow[T](a:T) extends Temp{
  def -->[B](b:B) = (a,b)
}
def foo(x : List[_ <: Temp]) = x

scala>     foo(List(1 --> 2))
res0: List[Temp] = List(Arrow@2e17a321)

这按预期工作。它没有抱怨,因为它正在搜索 Temp 而不是 Tuple2。 现在引入歧义:

implicit class OtherTemp[T](a:T) extends Temp{}
foo(List(1 --> 2)) //compile error

抱怨碰撞失败。所以回答你为什么没有显示 AnyRef 的问题是因为:

记住 ArrowAssoc 被调用以获得 AnyVal 表示。对于 ->,它有一个 Tuple2 并试图检索一个 AnyVal。并且因为它无法检索 AnyVal,它会将其标记为错误,因为无法转换为 AnyVal。它的真实身份无关紧要。

第一个问题: 以我的理解,隐式作为第一个搜索基础。所以一旦它找到两个并且有歧义,它就会停止抱怨。可能这就是为什么它不尝试使用 StringFormat 等。这可以通过重新排序隐式顺序

在 repl 上确认
implicit class OtherTemp2[T](a:T) extends Temp{
}
implicit class OtherTemp[T](a:T) extends Temp{
}

foo(List[Temp]("asdf"))

编译器抱怨 ArrowOtherTemp2 冲突。如果您重新排序并再次 运行 repl,它会根据首先发现的隐式进行抱怨。 但我找不到证实这一点的官方消息来源。