我现在看到有一个相关的问题,问这些运算符(
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]
是否为有效值。假设T
是Nothing
,那么作用域中将包含一个隐式值Nothing <:< Nothing
,这将允许您的方法调用进行编译。由于<:<
的定义方式sealed abstract class <:<[-From, +To]
允许
From
向上变化,允许To
向下变化。因此Nothing <:< Nothing
仍然是有效的Nothing <:< String
,因为Nothing
是String
的子类型。 String <:< String
也是有效的Nothing <:< String
,因为String
是Nothing
的超类型(但编译器似乎总是只选择第一种类型)。您可以在其上调用
String
的方法,因为<:<
还会扩展=>
aka Function1
并用作从T
到String
的隐式转换,这基本上可以进行安全的转换。=:=
是相同的东西,除了定义时没有任何方差注释,因此类型必须完全匹配。<%<
的定义类似于<:<
,但是隐式方法有点不同,它添加了另一个参数来指定视图范围implicit def conformsOrViewsAs[A <% B, B]: A <%< B
也已弃用。
关于scala - <:<,<%<,=:=的Scala实现在编译器中如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11488554/