简体   繁体   English

什么是`<:<`的隐式解析链

[英]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]
  1. Can anyone explain the implicit resolution chain here? 谁能在这里解释隐式解析链? How can $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调用引发异常,会发生什么?
  2. Why is the subclassing of => 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM