代码之家  ›  专栏  ›  技术社区  ›  Jesper

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

  •  102
  • Jesper  · 技术社区  · 14 年前

    当然,我首先搜索(例如 this )但我找不到任何真正清楚和详细的信息。

    4 回复  |  直到 7 年前
        1
  •  110
  •   Robert Harvey Isaac Blanco    14 年前

    你找到了吗 this article ? 它在数组改进的上下文中介绍了新的上下文绑定特性。

    上下文绑定 是那种形式的 [T: Bound] ; 它被扩展为普通类型参数 T Bound[T] .

    考虑一下这个方法 tabulate 从0到给定长度的一系列数字上的给定函数f。在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
    }
    

    在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
    }
    
        2
  •  150
  •   bbarker    6 年前

    罗伯特的回答涵盖了上下文边界的技术细节。我给你解释一下他们的意思。

    在Scala视图中( A <% B )抓住了“可视为”的概念,而 <: 抓住了“是”的概念。上下文绑定( A : C )对一种类型说“有”。您可以将清单的示例阅读为“ T Manifest ". 您链接到的示例 Ordered Ordering 说明了区别。一种方法

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

    表示参数可以看作 命令 . 比较

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

    .

    在使用方面,需要一段时间才能建立约定,但是上下文边界比视图边界更受欢迎( view bounds are now deprecated ClassManifest 用于创建数组)。

        3
  •  39
  •   retronym    14 年前

    (这是附加说明。先阅读并理解其他答案。)

    因此,给定用视图边界表示的代码:

    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
    

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

    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
    

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

    def f3[T : [X](X => String)](t: T) = 0 
    
        4
  •  19
  •   Community SushiHangover    7 年前

    这是另一个附加说明。

    作为 Ben pointed out ,上下文绑定表示类型参数和类型类之间的“has-a”约束。换句话说,它表示特定类型类的隐式值存在的约束。

    T : Ordering Ordering[T] 满足约束条件的。 As demonstrated here ,可以使用 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) }
    
    推荐文章