理解隐式<:<参数

时间:2016-08-14 15:20:18

标签: scala implicit

我写了这个例子

class TestMatch[T](private val t: T){
    def test()(implicit ev: T <:< Option[Int]) = println(ev(t).get)
}

并测试它

val tm = TestMatch(Some(10))
tm.test() //fine

val tm2 = TestMatch(10)
tm2.test() //compilation error

问题是,当我调用implicit ev: T <:< Option[Int]方法时,谁创建了test?我知道我没有。也许编译器知道implicit <:<并知道如何处理它。

<:<的记录不太清楚

  

约束方法中范围内的任何抽象类型T.   参数列表(不仅仅是方法自己的类型参数)只需添加   类型为 T <:< U的隐式参数,其中U是必需的   上限;或者对于下限,请使用:L <:< T,其中L   要求下限。

这是否意味着编译器将自己完成剩下的工作?我只是添加implicit ev: T1 <:< T2

3 个答案:

答案 0 :(得分:2)

第一个代码段由Predef.identity编译,这意味着您始终可以隐式将类型T转换为T类型(在本例中为Option[Int])。否则,你需要自己隐含进入scopre。

答案 1 :(得分:1)

  

这是否意味着编译器会自行完成剩下的工作?

编译器将搜索隐式范围。如果它找到匹配,它将提供它,如果它不能,你将得到编译错误。在您的示例中,编译器发现Some[Int]符合Some[Int] <:< Option[Int]的隐含要求,因为它是Option[Int]的直接子类型。

使用scalac编译代码时可以看到这一点:

val tm: TestMatch[Some[Int]] = new TestMatch[Some[Int]](scala.Some.apply[Int](10));
tm.test()(scala.this.Predef.$conforms[Some[Int]]);

Int(您的第二个示例)的位置,与要求匹配的范围没有隐含,Int不是Option[Int]的子类型。

答案 2 :(得分:1)

编译器将尝试在各种预定义位置查找隐式参数。如果它找不到它会引发错误。此链接可能有所帮助:http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html

enter image description here