Контекстные границы
Во многих ситуациях необязательно указывать имя параметра контекста явно, поскольку оно используется компилятором только в синтезированных аргументах для других параметров контекста. В таких случаях имя параметра определять не нужно и можно просто указать его тип.
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 = ...
Дополнительные сведения о границах контекста см. в ответе "Что такое границы контекста?".
Ссылки: