Scala 3 — 书籍

上下文界限

语言

在许多情况下,上下文参数 的名称不必明确提及,因为编译器仅在其他上下文参数的合成参数中使用它。在这种情况下,你无需定义参数名称,只需提供参数类型即可。

背景

例如,考虑一个方法 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 一样。

省略上下文参数

由于 ord 是方法 max 中的上下文参数,因此编译器可以在我们调用方法 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 FAQ 的“什么是上下文界限?”部分。

此页面的贡献者