我写了这个例子
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
?
答案 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