7

我现在看到有一个相关的问题,询问这些运算符 (<:<, <%<, =:=) 在这里做什么:

<:<、<%< 和 =:= 在 Scala 2.8 中是什么意思,它们在哪里记录?

但我仍然对他们的实施感到困惑。特别是,我假设一旦您放置了一个断言特定关系的隐式参数,那么您就可以使用变量,就好像它们已经自动正确地强制转换一样,例如,这将编译:

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

但是这在编译器中实际上是如何工作的呢?这些运算符是否有一些神奇的编译器支持,如果没有,允许它从定义中推断出这种关系的底层机制是什么?(这个机制是为了让这些运算符工作而特别添加的吗?它对这些特定的运算符有多具体?)你可以像这样放置一个额外的隐式参数似乎有点神奇,它会以某种方式改变编译器对类型的解释。

4

1 回答 1

8

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

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

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

当您尝试调用您的方法时,它会查找 type 的隐式值T <:< String。编译器将检查是否conforms[T]为有效值。假设T那么在范围内Nothing会有一个隐式值Nothing <:< Nothing,它将允许您的方法调用进行编译。由于方式<:<已定义

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

From可以向上变化,To也可以向下变化。所以 aNothing <:< Nothing仍然是有效的Nothing <:< String,因为Nothing它是 的子类型String。AString <:< String也是有效的Nothing <:< String,因为String它是的超类型Nothing(但编译器似乎总是只选择第一种类型)。

您可以调用它的方法,String因为它<:<也扩展了=>akaFunction1并用作从Tto的隐式转换String,这基本上最终会进行安全转换。

=:=是一样的,只是它没有任何方差注释定义,所以类型必须完全匹配。

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

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

它也已被弃用。

于 2012-07-15T05:57:49.230 回答