【问题标题】:Scala implicit resolution different for AnyVal?AnyVal的Scala隐式分辨率不同?
【发布时间】:2017-03-06 22:36:55
【问题描述】:

我正在为所有类型解析的伴随对象中定义隐式,除了 AnyVals,如 Long 和 Double 等。我不确定为什么会这样? 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]

【问题讨论】:

    标签: scala implicit


    【解决方案1】:

    编译器不知道如何解决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],编译器在作用域中找不到隐式,在SomeType或Long的伴生对象中也找不到,所以编译失败。 SomeType[Double] 因同样原因失败。

    如果您在Console 中使用import X._,它将起作用,因为这会将所有隐式都包含在范围内。如果你想为不同的类型提供SomeTypes 的默认隐式实例,最好将它们放在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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      • 2016-04-05
      • 2011-11-11
      • 2017-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多