什么是Scala中的“上下文绑定”?
Scala 2.8的新特性之一是上下文边界。 什么是上下文绑定,它在哪里有用?
当然,我首先search(例如发现这个 ),但我找不到任何清晰和详细的信息。
你有没有find这篇文章 ? 它涵盖了新的上下文绑定function,在arrays改进的上下文中。
通常情况下,带有上下文绑定的types参数的forms是[T: Bound]
; 它与一个types为Bound[T]
的隐式参数一起扩展为简单types参数T
考虑使用从0到给定长度的数字范围应用给定函数f的结果形成数组的方法tabulate
。 截至Scala 2.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 }
在Scala 2.8中,这是不可能的,因为运行时信息是创buildArray[T]
的正确表示所必需的。 需要通过将ClassManifest[T]
作为隐式parameter passing给方法来提供这些信息:
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 }
作为一种简写forms, 上下文绑定可以用在types参数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 }
罗伯特的回答涵盖了语境的技术细节。 我会给你我的解释他们的意思。
在Scala中,一个视图绑定( A <% B
)捕获“可以被视为”的概念(而上界<:
捕获'是'的概念)。 上下文绑定( A : C
)表示'有'有关types。 您可以阅读有关舱单的例子,如“ T
有Manifest
”。 你链接到的Ordered
与Ordering
例子说明了这个区别。 一个方法
def example[T <% Ordered[T]](param: T)
说这个参数可以看作是Ordered
。 与之比较
def example[T : Ordering](param: T)
其中说参数有一个相关的Ordering
。
在使用方面,我不认为惯例是正确的(因为语境是新的)。 一个build议是,当你需要将一个隐式定义从一个范围转移到另一个范围而不需要直接引用时(这对于用于创build数组的ClassManifest
来说当然是这种情况),它们的使用是首选。
考虑视图边界和上下文边界的另一种方式是,第一个调用从调用者的范围转移隐式转换。 第二个从调用者的作用域传递隐式对象。
(这是一个括号,先阅读并理解其他答案。)
上下文边界实际上概括了视图边界。
所以,考虑到这个代码用一个视图边界来表示:
scala> implicit def int2str(i: Int): String = i.toString int2str: (i: Int)String scala> def f1[T <% String](t: T) = 0 f1: [T](t: T)(implicit evidence$1: (T) => String)Int
这也可以用一个上下文绑定来表示,借助于一个types别名来表示从typesF
到typesT
函数。
scala> trait To[T] { type From[F] = F => T } defined trait To scala> def f2[T : To[String]#From](t: T) = 0 f2: [T](t: T)(implicit evidence$1: (T) => java.lang.String)Int scala> f2(1) res1: Int = 0
上下文绑定必须与types* => *
的types构造函数一起使用。 但是types构造Function1
是类(*, *) => *
。 types别名的使用部分地将第二types参数应用于typesString
,产生用作上下文绑定的正确types的types构造器。
有一个build议,允许你直接expression在Scala中部分应用的types,而不使用特征中的types别名。 然后你可以写:
def f3[T : [X](X => String)](t: T) = 0
这是另一个附注。
正如Ben所指出的那样 ,上下文绑定表示types参数和types类之间的“has-a”约束。 换句话说,它代表了一个特定types类的隐式值存在的约束。
当使用上下文绑定时,通常需要表示该隐式值。 例如,给定约束T : Ordering
,通常需要满足约束条件的Ordering[T]
的实例。 如此处所示 ,可以通过使用implicitly
方法或稍微更有用的context
方法来访问隐式值:
def **[T : Numeric](xs: Iterable[T], ys: Iterable[T]) = xs zip ys map { t => implicitly[Numeric[T]].times(t._1, t._2) }
要么
def **[T : Numeric](xs: Iterable[T], ys: Iterable[T]) = xs zip ys map { t => context[T]().times(t._1, t._2) }