[英]What is the implicit resolution chain of `<:<`
The compiler is able to provide evidence about type parameters, eg: 编译器能够提供有关类型参数的证据,例如:
def foo[A, B](implicit ev: A <:< B): B
A look at the type definition for <:<
in Predef
shows 查看
Predef
中<:<
的类型定义
sealed abstract class <:<[-From, +To] extends (From => To) with Serializable
private[this] final val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x }
implicit def $conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]
$conforms[A]: A <:< A
convince the compiler to create an instance of <:<[List[String], Seq[String]]
for instance? $conforms[A]: A <:< A
说服编译器例如创建<:<[List[String], Seq[String]]
的实例? Or <:<[Dog, Animal]
. <:<[Dog, Animal]
。 And what happens if (when) the .asInstanceOf
call throws an exception? .asInstanceOf
调用引发异常,会发生什么? =>
necessary? =>
的子类化是必需的? You can see it in the scala.Predef
object: https://github.com/scala-native/scala-native/blob/master/scalalib/overrides-2.11/scala/Predef.scala#L372 您可以在
scala.Predef
对象中看到它: https : //github.com/scala-native/scala-native/blob/master/scalalib/overrides-2.11/scala/Predef.scala#L372
@implicitNotFound(msg = "Cannot prove that ${From} <:< ${To}.")
sealed abstract class <:<[-From, +To] extends (From => To) with Serializable
private[this] lazy val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x }
@inline implicit def $conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]
@deprecated("Use `implicitly[T <:< U]` or `identity` instead.", "2.11.0")
def conforms[A]: A <:< A = $conforms[A]
<:<[-From, +To]
contravariant over Form
and covariant over To
, hence <:<[Seq[String], Seq[String]]
is a subtype of <:<[List[String], Seq[String]]
(because List[String]
is a subtype of Seq[String]
and -From
is contravariant). <:<[-From, +To]
在Form
协变的,在To
协变的,因此<:<[Seq[String], Seq[String]]
是<:<[List[String], Seq[String]]
(因为List[String]
是Seq[String]
的子类型,而-From
是反变量)。 So, when you write implicit ev List[String] <:< Seq[String]
the compiler use <:<[Seq[String], Seq[String]]
因此,当您编写
implicit ev List[String] <:< Seq[String]
,编译器将使用<:<[Seq[String], Seq[String]]
When you write implicit ev T <:< D
and there is no A
that conforms T <: A <: D
, the compiler doesn't compile it, because there is no <:<[A, A]
that conforms <:<[A, A] <: <:<[T, D]
. 当你写
implicit ev T <:< D
没有A
符合T <: A <: D
,编译器不编译它,因为没有<:<[A, A]
符合<:<[A, A] <: <:<[T, D]
。 So, .asInstanceOf
never throws an exception inside $conforms
in runtime. 因此,
.asInstanceOf
永远不会在运行时的$conforms
.asInstanceOf
内部引发异常。
Also, a very good blog post about it: http://blog.bruchez.name/2015/11/generalized-type-constraints-in-scala.html 另外,关于此的非常好的博客文章: http : //blog.bruchez.name/2015/11/generalized-type-constraints-in-scala.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.