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

发布于 2024-10-15 09:02:25 字数 123 浏览 1 评论 0原文

我见过 <:>:<% 等。有人可以给出(或定位)一个好的描述吗这些?可能的限制是什么,它们有什么作用,以及何时使用它们的示例是什么?

I've seen <:, >:, <%, etc. Can someone give (or locate) a good description of these? What are the possible constraints, what do they do, and what's an example of when to use them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

各空 2024-10-22 09:02:25

S <: T 表示 ST 的子类型。这也称为上类型界限。类似地,S >: T 表示 ST 的超类型,一个 较低的类型界限

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

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

S <: T means that S is a subtype of T. This is also called an upper type bound. Similarly, S >: T means that S is a supertype of T, a lower type bound.

S <% T is a view bound, and expresses that S must come equipped with a view that maps its values into values of type T.

It's confusing for me too, and I have a Masters in programming languages from Berkeley.

深巷少女 2024-10-22 09:02:25

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

首先是类型边界:

  • <: - 上部类型边界
  • > : - 较低类型界限

这些本质上与 java 中的 superextends 相同,并且实际上会在生成的字节码中进行编码,这很好对于互操作:)

然后是语法糖:

  • <% - 视图绑定
  • : - 上下文绑定

这些不是以 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

对于此原因是,您不能将自己的隐式与视图边界或上下文边界结合起来,因为 Scala 只允许任何函数或构造函数将一个标记为隐式的块。

如果您确实需要使用自己的隐式,那么您必须首先手动将任何此类边界转换为未加糖的版本,并将其添加到隐式块中。

There are two different beasts here, but they're all know as "bounds" and not "constraints"...

First are the type bounds:

  • <: - uppper type bound
  • >: - lower type bound

These are essentially the same as super and extends in java, and will actually be encoded as such in the generated bytecode, which is good for interop :)

Then comes the syntactic sugar:

  • <% - view bound
  • : - context bound

These are NOT encoded in a way that Java could possibly understand (although they are represented in the scala signature, an annotation that scala adds to all classes to help the compiler, and which would ultimately be the base of an Scala reflection library)

Both of these are converted to implicit parameters:

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

For this reason, you can't combine your own implicits with either view bounds or context bounds, as Scala only permits one block labelled as implicit for any function or constructor.

If you do need to use your own implicits then you must first manually convert any such bounds to the unsugared version and add this to the implicit block.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文