什么是“上下文绑定”?在斯卡拉?
Scala 2.8 的新功能之一是上下文边界。什么是上下文绑定以及它在哪里有用?
当然,我首先搜索(并发现例如 this),但我找不到任何真正清晰详细的信息。
One of the new features of Scala 2.8 are context bounds. What is a context bound and where is it useful?
Of course I searched first (and found for example this) but I couldn't find any really clear and detailed information.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
罗伯特的回答涵盖了上下文边界的技术细节。我将向您解释它们的含义。
在 Scala 中,视图边界 (
A <% B
) 捕获“可以被视为”的概念(而上限<:
捕获“是”的概念一个')。上下文绑定 (A : C
) 表示关于类型的“有一个”。您可以将有关清单的示例阅读为“T
has aManifest
”。您链接到的有关Ordered
与Ordering
的示例说明了其中的差异。方法表示该参数可以被视为
Ordered
。与它进行比较,表明该参数具有关联的
Ordering
。在使用方面,建立约定需要一段时间,但上下文边界优于视图边界(视图边界现已弃用)。一个建议是,当您需要将隐式定义从一个作用域传输到另一个作用域而不需要直接引用它时,首选上下文绑定(对于用于创建数组的
ClassManifest
来说肯定是这种情况) )。考虑视图边界和上下文边界的另一种方式是,第一种方式从调用者的作用域传输隐式转换。第二个从调用者的范围传输隐式对象。
Robert's answer covers the techinal details of Context Bounds. I'll give you my interpretation of their meaning.
In Scala a View Bound (
A <% B
) captures the concept of 'can be seen as' (whereas an upper bound<:
captures the concept of 'is a'). A context bound (A : C
) says 'has a' about a type. You can read the examples about manifests as "T
has aManifest
". The example you linked to aboutOrdered
vsOrdering
illustrates the difference. A methodsays that the parameter can be seen as an
Ordered
. Compare withwhich says that the parameter has an associated
Ordering
.In terms of use, it took a while for conventions to be established, but context bounds are preferred over view bounds (view bounds are now deprecated). One suggestion is that a context bound is preferred when you need to transfer an implicit definition from one scope to another without needing to refer to it directly (this is certainly the case for the
ClassManifest
used to create an array).Another way of thinking about view bounds and context bounds is that the first transfers implicit conversions from the caller's scope. The second transfers implicit objects from the caller's scope.
您找到这篇文章了吗?它涵盖了数组改进上下文中的新上下文绑定功能。
一般来说,具有上下文绑定的类型参数的形式为
[T: Bound]
;它被扩展为普通类型参数T
以及类型Bound[T]
的隐式参数。考虑一下
tabulate
方法,它根据应用的结果形成一个数组给定函数 f,作用于从 0 到给定长度的数字范围。到 Scala 2.7,表格可以是
编写如下:
在 Scala 2.8 中,这不再可能,因为需要运行时信息来创建
Array[T]
的正确表示。需要通过将ClassManifest[T]
作为隐式参数传递到方法中来提供此信息:作为一种简写形式,可以在类型参数上使用上下文绑定相反,使用
T
给出:Did you find this article? It covers the new context bound feature, within the context of array improvements.
Generally, a type parameter with a context bound is of the form
[T: Bound]
; it is expanded to plain type parameterT
together with an implicit parameter of typeBound[T]
.Consider the method
tabulate
which forms an array from the results of applyinga given function f on a range of numbers from 0 until a given length. Up to Scala 2.7, tabulate could be
written as follows:
In Scala 2.8 this is no longer possible, because runtime information is necessary to create the right representation of
Array[T]
. One needs to provide this information by passing aClassManifest[T]
into the method as an implicit parameter:As a shorthand form, a context bound can be used on the type parameter
T
instead, giving:(这是一个括号注释。首先阅读并理解其他答案。)
上下文边界实际上概括了视图边界。
因此,给定用 View Bound 表达的代码:
这也可以用 Context Bound 表达,并借助表示从类型
F
到类型T
的函数的类型别名。上下文绑定必须与
* => 类型的类型构造函数一起使用。 *。然而,类型构造函数
Function1
的类型是(*, *) =>; *。类型别名的使用部分应用了
String
类型的第二个类型参数,生成正确类型的类型构造函数以用作上下文绑定。有一项提议允许您直接在 Scala 中表达部分应用的类型,而无需在特征中使用类型别名。然后你可以写:
(This is a parenthetical note. Read and understand the other answers first.)
Context Bounds actually generalize View Bounds.
So, given this code expressed with a View Bound:
This could also be expressed with a Context Bound, with the help of a type alias representing functions from type
F
to typeT
.A context bound must be used with a type constructor of kind
* => *
. However the type constructorFunction1
is of kind(*, *) => *
. The use of the type alias partially applies second type parameter with the typeString
, yielding a type constructor of the correct kind for use as a context bound.There is a proposal to allow you to directly express partially applied types in Scala, without the use of the type alias inside a trait. You could then write:
这是另一个括号注释。
如 Ben 指出,上下文绑定表示类型参数和类型类之间的“has-a”约束。换句话说,它表示存在特定类型类的隐式值的约束。
当使用上下文绑定时,人们通常需要显示该隐式值。例如,给定约束
T : Ordering
,人们通常需要满足该约束的Ordering[T]
实例。 如此处所示,可以使用implicitly
方法或稍微有用的context
方法来访问隐式值:或者
This is another parenthetical note.
As Ben pointed out, a context bound represents a "has-a" constraint between a type parameter and a type class. Put another way, it represents a constraint that an implicit value of a particular type class exists.
When utilizing a context bound, one often needs to surface that implicit value. For example, given the constraint
T : Ordering
, one will often need the instance ofOrdering[T]
that satisfies the constraint. As demonstrated here, it's possible to access the implicit value by using theimplicitly
method or a slightly more helpfulcontext
method:or