Контекстные границы

Во многих ситуациях необязательно указывать имя параметра контекста явно, поскольку оно используется компилятором только в синтезированных аргументах для других параметров контекста. В таких случаях имя параметра определять не нужно и можно просто указать его тип.

Background

Например, этот метод maximum принимает параметр контекста типа Ord только для того, чтобы передать его в качестве аргумента функции max:

def maximum[A](xs: List[A])(using ord: Ord[A]): A =
  xs.reduceLeft(max(ord))

В этом коде имя параметра ord на самом деле не требуется; его можно передать в качестве предполагаемого аргумента в max, поэтому достаточно просто указать, что maximum использует тип Ord[A], не называя его:

def maximum[A](xs: List[A])(using Ord[A]): A =
  xs.reduceLeft(max)

Контекстные границы

Учитывая вышесказанное, контекстная граница (context bound) — это сокращенный синтаксис для выражения шаблона "параметр контекста, который зависит от параметра типа".

Используя привязку к контексту, метод maximum можно записать следующим образом:

def maximum[A: Ord](xs: List[A]): A = xs.reduceLeft(max)

Привязка типа : Ord к параметру типа A метода или класса указывает параметр контекста using Ord[A].

Параметры контекста, сгенерированные из границ контекста, идут последними в определении содержащего их метода или класса. Например,

def f[T: C1 : C2, U: C3](x: T)(using y: U, z: V): R

расширится до

def f[T, U](x: T)(using y: U, z: V)(using C1[T], C2[T], C3[U]): R

Границы контекста можно комбинировать с границами подтипа. Если присутствуют оба, сначала идут границы подтипа, например

def g[T <: B : C](x: T): R = ...

Дополнительные сведения о границах контекста см. в ответе "Что такое границы контекста?".


Ссылки: