简体   繁体   English

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

[英]Scala implicit resolution different for AnyVal?

I am defining implicits in companion objects that get resolved for all types except AnyVals such as Long and Double etc. I am not exactly sure why it is the case? 我在伴侣对象中定义implicits,除了AnyVals(如Long和Double等)之外,所有类型都会解析。我不确定为什么会这样? Are there different resolution rules for AnyVals? 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]

The compiler doesn't know how to resolve these two implicits within object X : 编译器不知道如何解决object X这两个含义:

implicit def ll = LType
implicit def dd = DType

Calling new X(3).add[X] is able to resolve a SomeType[X] because when looking for an implicit SomeType[X] , the compiler will look within the companion object of X (among other places, see Where does Scala look for implicits? ), and it finds it as implicit def xx = XType . 调用new X(3).add[X]能够解析SomeType[X]因为在查找隐式SomeType[X] ,编译器将查看X的伴随对象(在其他地方,请参阅Scala在哪里)寻找implicits? ),它发现它是implicit def xx = XType

For SomeType[Long] , the compiler can't find the implicit in scope, nor it is available within the companion objects of SomeType or Long , so it fails. 对于SomeType[Long] ,编译器无法找到隐含的范围,也无法在SomeTypeLong的伴随对象中SomeType ,因此失败。 SomeType[Double] fails for the same reason. SomeType[Double]因同样的原因失败。

If you import X._ within Console it will work, because that would bring all of the implicits within scope. 如果您在Console import X._它将起作用,因为这将带来范围内的所有隐含。 If you want to provide default implicit instances of SomeType s for different types, it would be best to place them within the companion of SomeType . 如果要为不同类型提供SomeType的默认隐式实例,最好将它们放在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]
}

The following will always work now, no matter where you call them: 无论您在何处呼叫,以下内容始终有效:

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

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

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

In short, it has nothing to do with AnyVal . 简而言之,它与AnyVal You could have added a SomeType[String] alongside the others and had the same issue. 你可以在其他人的同时添加SomeType[String]并遇到同样的问题。 The difference was that you were treating X specially. 不同之处在于你特意对待X

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM