【问题标题】:What is the implicit resolution chain of `<:<``<:<`的隐式解析链是什么
【发布时间】:2018-09-28 09:53:35
【问题描述】:

编译器能够提供关于类型参数的证据,例如:

def foo[A, B](implicit ev: A <:< B): B

Predef 节目中查看&lt;:&lt; 的类型定义

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. 谁能解释这里的隐式解析链?例如,$conforms[A]: A &lt;:&lt; A 如何说服编译器创建&lt;:&lt;[List[String], Seq[String]] 的实例?或&lt;:&lt;[Dog, Animal]。如果(何时).asInstanceOf 调用引发异常会发生什么?
  2. 为什么=&gt; 的子类化是必要的?

【问题讨论】:

  • 启用它的是&lt;:&lt; 类上的差异。

标签: scala


【解决方案1】:

您可以在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]

&lt;:&lt;[-From, +To]Form 上逆变,在To 上协变,因此&lt;:&lt;[Seq[String], Seq[String]]&lt;:&lt;[List[String], Seq[String]] 的子类型(因为List[String]Seq[String] 的子类型而-From 是逆变的)。因此,当您编写 implicit ev List[String] &lt;:&lt; Seq[String] 时,编译器使用 &lt;:&lt;[Seq[String], Seq[String]]

当您编写implicit ev T &lt;:&lt; D 并且没有符合T &lt;: A &lt;: DA 时,编译器不会编译它,因为没有符合&lt;:&lt;[A, A] &lt;: &lt;:&lt;[T, D]&lt;:&lt;[A, A]。所以,.asInstanceOf 在运行时从不会在$conforms 内部抛出异常。

另外,一篇关于它的非常好的博客文章:http://blog.bruchez.name/2015/11/generalized-type-constraints-in-scala.html

【讨论】:

    猜你喜欢
    • 2021-06-03
    • 2010-12-19
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 2010-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多