识别并描述Scala的泛型类型约束

Ale*_*ack 45 generics scala

我见过"<:"和">:"和"<%"等,有人能给(或找到)这些的好描述吗?有什么可能的限制,他们做了什么,以及什么时候使用它们的例子?

Rap*_*ien 68

S <: T意味着它S是一个子类型T.这也称为上限类型.类似地,S >: T表示属于较低类型边界S的超类型.T

S <% T是一个视图绑定,并表示S必须配备一个视图,将其值映射到类型的值T.

这对我来说也很困惑,而且我还拥有伯克利的编程语言硕士学位.

  • 最后谦虚吹嘘:-)大声笑.谢谢你的回答 (3认同)
  • 在Scala 2.11中,BTW视图边界被[不推荐使用](https://issues.scala-lang.org/browse/SI-7629). (2认同)

Kev*_*ght 54

这里有两种不同的野兽,但它们都被称为"界限"而不是"约束"......

首先是类型边界:

  • <: - uppper类型绑定
  • >: - 下限类型

这些是基本上相同superextends在Java中,并实际上将在生成的字节码,这是很好的互操作被编码为这样的:)

然后是句法糖:

  • <% - 查看绑定
  • : - 上下文绑定

这些不是以Java可能理解的方式编码的(尽管它们在scala签名中表示,scala添加到所有类以帮助编译器的注释,以及最终将成为Scala反射库的基础的注释)

这两个都转换为隐式参数:

def fn[A <% B](arg: A)  = ... //sugared
def fn[A](arg: A)(implicit ev: A => B) = ... //unsugared

def fn[A : Numeric](arg: A)  = ... //sugared
def fn[A](arg: A)(implicit ev: Numeric[A]) = ... //unsugared
Run Code Online (Sandbox Code Playgroud)

因此,您不能将自己的implicits与视图边界或上下文边界组合在一起,因为Scala只允许为任何函数或构造函数标记为隐式的一个块.

如果确实需要使用自己的implicits,则必须先将任何此类边界手动转换为unsugared版本,然后将其添加到隐式块中.