2017-03-06 64 views
1

我定义了伴随对象中的含义,除了AnyVals之外的所有类型(如Long和Double等)都可以解析。我不完全确定它为什么是这种情况? AnyVals有不同的解析规则吗?对于AnyVal,Scala隐式分辨率不同?

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] 

回答

3

编译器不知道如何内object X解决这两个implicits:

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的伴随内。

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