Scala隐式分辨率对AnyVal有何不同?

时间:2017-03-06 22:36:55

标签: scala implicit

我正在为除了AnyVals之外的所有类型(如Long和Double等)解析的伴随对象中定义implicits。我不确定为什么会这样? AnyVals有不同的解决方案规则吗?

class X(val i:Int) {
  def add[T](implicit x:SomeType[T])=println(x)
}
object X {
  implicit def xx = XType
  implicit def ll = LType
  implicit def dd = DType
}

object Console {
  def main(args: Array[String]): Unit = {
    new X(3).add[X] // works fine
    new X(3).add[Long] // error Error:(16, 16) could not find implicit value for parameter x: com.x.SomeType[Long]
    new X(3).add[Double] // error Error:(16, 16) could not find implicit value for parameter x: com.x.SomeType[Double]
  }
}

sealed trait SomeType[T]

case object XType extends SomeType[X]
case object LType extends SomeType[Long]
case object DType extends SomeType[Double]

1 个答案:

答案 0 :(得分:3)

编译器不知道如何解决object X中的这两个含义:

implicit def ll = LType
implicit def dd = DType

调用new X(3).add[X]能够解析SomeType[X],因为在查找隐式SomeType[X]时,编译器会查找X的伴随对象(在其他位置,请参阅Where does Scala look for implicits?),并将其视为implicit def xx = XType

对于SomeType[Long],编译器无法找到隐含的范围,也无法在SomeTypeLong的配对对象中使用,因此失败。 SomeType[Double]因同样的原因失败。

如果你import X._ Console内的SomeType它会起作用,因为这会带来范围内的所有暗示。如果要为不同类型提供SomeType s的默认隐式实例,最好将它们放在class X(val i:Int) { def add[T](implicit x: SomeType[T]) = println(x) } sealed trait SomeType[T] object SomeType { implicit case object XType extends SomeType[X] implicit case object LType extends SomeType[Long] implicit case object DType extends SomeType[Double] } 的伴随中。

scala> new X(3).add[X]
XType

scala> new X(3).add[Long]
LType

scala> new X(3).add[Double]
DType

无论您在何处呼叫,以下内容始终有效:

AnyVal

简而言之,它与SomeType[String]无关。您可以在其他人旁边添加X并遇到同样的问题。不同之处在于您专门处理var lookupsClient = new LookupsClient(accountSid, authToken);