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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4869988/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:46:46  来源:igfitidea点击:

Identify and describe Scala's generic type constraints

genericsscala

提问by Alex Black

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?

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

回答by Raph Levien

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

S <: T表示它S是 的子类型T。这也称为类型上限。类似地,S >: T意味着它S是 的超类型T下限类型

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

S <% T是一个视图边界,并表示S必须配备一个视图,将其值映射为类型的值T

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

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

回答by Kevin Wright

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 superand extendsin java, and will actually be encoded as such in the generated bytecode, which is good for interop :)

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

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)

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

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.

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

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.

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