AnyVal的Scala隐式分辨率不同



我在伴随对象中定义隐含的含义,这些对象可以解决所有类型的解决方案,除了long和double等。我不确定为什么是这种情况?是否有不同的分辨率规则?

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]

编译器不知道如何在 object X中解析这两个隐含物:

implicit def ll = LType
implicit def dd = DType

调用new X(3).add[X]能够解析SomeType[X],因为在寻找隐式SomeType[X]时,编译器将在X的伴随对象中查找(除其他地方,请参见Scala在哪里寻找隐性吗?),它将其作为implicit def xx = XType

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

如果您在Console中的import X._,它将起作用,因为这将带来范围内的所有隐含物。如果要为不同类型的SomeType s提供默认的隐式实例,则最好将它们放在SomeType的同伴中。

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

相关内容

  • 没有找到相关文章

最新更新