为了账号安全,请及时绑定邮箱和手机立即绑定

什么是Scala中的“上下文绑定”?

什么是Scala中的“上下文绑定”?

白衣染霜花 2019-07-15 09:58:47
什么是Scala中的“上下文绑定”?Scala2.8的一个新特性是上下文边界。什么是上下文约束,它在哪里有用?当然,我首先搜索了(例如发现)这,这个但我找不到任何真正清晰和详细的信息。
查看完整描述

3 回答

?
子衿沉夜

TA贡献1828条经验 获得超3个赞

类的类型参数。上下文约束是形式上的[T: Bound],它被扩展为普通类型参数。T与类型的隐式参数一起使用。Bound[T].

考虑一下方法tabulate它由对从0到给定长度的数字范围内应用给定函数f的结果形成数组。到Scala2.7,表格可以写成如下:

def tabulate[T](len: Int, f: Int => T) = {
    val xs = new Array[T](len)
    for (i <- 0 until len) xs(i) = f(i)
    xs}

在Scala2.8中,这已经不可能了,因为创建正确的表示形式需要运行时信息。Array[T]..需要通过传递ClassManifest[T]作为隐式参数进入该方法:

def tabulate[T](len: Int, f: Int => T)(implicit m: ClassManifest[T]) = {
    val xs = new Array[T](len)
    for (i <- 0 until len) xs(i) = f(i)
    xs}

作为速记形式,上下文约束可用于类型参数。T相反,给予:

def tabulate[T: ClassManifest](len: Int, f: Int => T) = {
    val xs = new Array[T](len)
    for (i <- 0 until len) xs(i) = f(i)
    xs}


查看完整回答
反对 回复 2019-07-15
?
开满天机

TA贡献1786条经验 获得超12个赞

在Scala中,视图绑定(A <% B)抓住了“可以视为”的概念(而上界则是<:捕捉“is a”的概念)。上下文约束(A : C)说“有一种类型”。您可以将有关清单的示例阅读为“T有一个Manifest“.您链接到的关于OrderedVSOrdering说明了不同之处。一种方法

def example[T <% Ordered[T]](param: T)

表示该参数可视为Ordered..相比较

def example[T : Ordering](param: T)

,该参数具有关联的Ordering.

就使用而言,需要一段时间才能建立约定,但上下文界限比视图边界更可取(视图边界现在不再受欢迎。)。一种建议是,当您需要将隐式定义从一个作用域转移到另一个作用域时,上下文绑定是首选的,而不需要直接引用它(对于ClassManifest用于创建数组)。

另一种考虑视图边界和上下文边界的方法是,第一种方法是从调用方的作用域传递隐式转换。第二个从调用者的作用域传输隐式对象。


查看完整回答
反对 回复 2019-07-15
?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

上下文边界实际上是视图边界的概括。

因此,给定这个用视图绑定表示的代码:

scala> implicit def int2str(i: Int): String = i.toString
int2str: (i: Int)Stringscala> def f1[T <% String](t: T) = 0f1: [T](t: T)(implicit evidence$1: (T) => String)Int

这也可以通过上下文绑定来表示,可以借助类型别名来表示类型中的函数。F键入T.

scala> trait To[T] { type From[F] = F => T }          
 defined trait Toscala> def f2[T : To[String]#From](t: T) = 0    
    f2: [T](t: T)(implicit evidence$1: (T) => java.lang.String)Intscala> f2(1)res1: Int = 0

上下文绑定必须与类的类型构造函数一起使用。* => *..但是,类型构造函数Function1是一种(*, *) => *..类型别名的使用部分地将第二个类型参数与类型一起应用。String,生成正确类型的类型构造函数,用作上下文绑定。

有一项建议允许您在Scala中直接表示部分应用的类型,而无需在特征中使用类型别名。然后你可以写:

def f3[T : [X](X => String)](t: T) = 0


查看完整回答
反对 回复 2019-07-15
  • 3 回答
  • 0 关注
  • 531 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信