实现evidence关键字的视图边界和类型边界之间有什么区别?

时间:2015-04-24 18:16:30

标签: scala

我不确定我的标题中是否有正确的术语,但这有什么区别:

class Container[A <% Int] { def addIt(x: A) = 123 + x }

和此:

class Container[A](value: A) { def addIt(implicit evidence: A =:= Int) = 123 + value }

我想问的问题是为什么我会使用一种类型绑定另一种形式?是否只是能够在代码的不同部分应用绑定的类型(例如在参数列表与正文中)?

此外,文档说方法可能会询问类型的“证据”,而不是使用其他对象进行类型检查,然后提供第二个代码段。他们指的是什么样的证据?

注意:这是关于高级类型的this文章。

1 个答案:

答案 0 :(得分:4)

查看边界适用于您希望使用 viewable 类型作为其他类型的情况。在您的示例中,您希望A 可查看Int。这意味着我们希望A => Int范围内的任何隐式转换。

即。它与:

相同
class Container(implicit evidence: A => Int) { def addIt(x: A) = 123 + x }

他们也是deprecated。这应该足以避免它们。

类型边界不是第二个示例的正确术语。它们用于严格限制上面或下面的参数类型。 类型绑定将如下所示:

class Container[A <: Int] { def addIt(x: A) = 123 + x }

在此示例中,A必须严格限制在Int之上。隐式转换不适用。

我不确定您的第二个示例是否真的有名称,但它与 view bounds 的不同之处在于它需要类型为{{1}的实例看到here。它类似于=:=见证人的=:=A相同的视图界限,因此允许Int明确转换为A。但是,它需要存在类型类Int的实例,而不仅仅是来自=:=[A, Int]任何隐式转换。

你的两个例子虽然有点根本不同。第一个要求类本身的视图绑定,其中第二个需要方法的类型证据。也就是说,第一个示例不允许A => Int的实例存在(没有可用的隐式转换),但第二个示例。第二个示例很乐意允许您构建Container[String],但不允许您使用Container[String]方法,除非您有addIt的证据。

通过证据,我们指的是隐式转换为我们对(String =:= Int)感兴趣的类型,或者是类型为A => Int的类型的实例平等。对于实际相同的类型,我们会在Predef (earlier link)中自动生成这些类型。