Scala 3 — Book

上下文绑定

Language

在许多情况下,上下文参数 的名称不必显式提及,因为它仅在编译器为其他上下文参数合成实参的时候用到。 在这种情况下,您不必定义参数名称,只需提供参数类型即可。

背景

例如,假设一个 maxElement 方法返回一个集合里的最大值:

def maxElement[A](as: List[A])(implicit ord: Ord[A]): A =
  as.reduceLeft(max(_, _)(ord))
def maxElement[A](as: List[A])(using ord: Ord[A]): A =
  as.reduceLeft(max(_, _)(using ord))

上面这个 maxElement 方法只接受一个类型为 Ord[A]上下文参数 并将其作为实参传给 max 方法。

完整起见,以下是 maxOrd 的定义(注意,在实践中我们会使用 List 中已有的 max 方法 , 但我们为了说明目的而编造了这个例子):

/** Defines how to compare values of type `A` */
trait Ord[A] {
  def greaterThan(a1: A, a2: A): Boolean
}

/** Returns the maximum of two values */
def max[A](a1: A, a2: A)(implicit ord: Ord[A]): A =
  if (ord.greaterThan(a1, a2)) a1 else a2
/** Defines how to compare values of type `A` */
trait Ord[A]:
  def greaterThan(a1: A, a2: A): Boolean

/** Returns the maximum of two values */
def max[A](a1: A, a2: A)(using ord: Ord[A]): A =
  if ord.greaterThan(a1, a2) then a1 else a2

max 方法用了类型为 Ord[A] 的上下文参数, 就像 maxElement 方法一样。

省略上下文参数

因为 ordmax 方法的上下文参数,当我们调用方法 max 时, 编译器可以在 maxElement 的实现中为我们提供它:

def maxElement[A](as: List[A])(implicit ord: Ord[A]): A =
  as.reduceLeft(max(_, _))
def maxElement[A](as: List[A])(using Ord[A]): A =
  as.reduceLeft(max(_, _))

注意,因为我们不用显示传递给 max 方法,我们可以在 maxElement 定义里不命名。 这是 匿名上下文参数

上下文绑定

鉴于此背景,上下文绑定 是一种简写语法,用于表达“依赖于类型参数的上下文参数”模式。

使用上下文绑定,maxElement 方法可以这样写:

def maxElement[A: Ord](as: List[A]): A =
  as.reduceLeft(max(_, _))

方法或类的类型参数 A,有类似 :Ord 的绑定,它表示有 Ord[A] 的上下文参数。 在后台,编译器将此语法转换为“背景”部分中显示的语法。

有关上下文绑定的更多信息,请参阅 Scala 常见问题解答的 “什么是上下文绑定?” 部分。

Contributors to this page: