我现在看到有一个相关的问题,问这些运算符(
What do <:<, <%<, and =:= mean in Scala 2.8, and where are they documented?

但是我仍然对它们的实现感到困惑。特别是,我假设一旦您放置了一个隐式参数来声明特定的关系,便可以使用变量,就好像变量已被自动正确地转换一样,例如这将编译:

class Foo[T](a: T) {
  def splitit(implicit ev: T <:< String) = a split " "
}


但是,这在编译器中实际上如何工作?这些运算符是否有某种神奇的编译器支持,如果没有,那么允许它从定义中推断出这种关系的基础机制是什么? (此机制是专门为允许这些运算符工作而添加的,以及对这些特定运算符有多特定?)您可以放置​​一个这样的额外隐式参数,以某种方式更改编译器对类型的解释,这似乎有点神奇。

最佳答案

该实现有些棘手,但没有什么神奇的。

Predef中有一个隐式方法,可以为任何A <:< A提供类型为A的值

implicit def conforms[A]: A <:< A


当您尝试调用您的方法时,它将查找类型为T <:< String的隐式值。编译器将检查conforms[T]是否为有效值。假设TNothing,那么作用域中将包含一个隐式值Nothing <:< Nothing,这将允许您的方法调用进行编译。由于<:<的定义方式

sealed abstract class <:<[-From, +To]


允许From向上变化,允许To向下变化。因此Nothing <:< Nothing仍然是有效的Nothing <:< String,因为NothingString的子类型。 String <:< String也是有效的Nothing <:< String,因为StringNothing的超类型(但编译器似乎总是只选择第一种类型)。

您可以在其上调用String的方法,因为<:<还会扩展=> aka Function1并用作从TString的隐式转换,这基本上可以进行安全的转换。

=:=是相同的东西,除了定义时没有任何方差注释,因此类型必须完全匹配。

<%<的定义类似于<:<,但是隐式方法有点不同,它添加了另一个参数来指定视图范围

implicit def conformsOrViewsAs[A <% B, B]: A <%< B


也已弃用。

关于scala - <:<,<%<,=:=的Scala实现在编译器中如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11488554/

10-13 05:29