Scala 3 — Book

Параметризованные типы

Language

Универсальные (generic) классы (или trait-ы) принимают тип в качестве параметра в квадратных скобках [...]. Для обозначения параметров типа согласно конвенции Scala используется одна заглавная буква (например, A). Затем этот тип можно использовать внутри класса по мере необходимости для параметров экземпляра метода или для возвращаемых типов:

// здесь мы объявляем параметр типа A
//          v
class Stack[A] {
  private var elements: List[A] = Nil
  //                         ^
  //  здесь мы ссылаемся на этот тип
  //          v
  def push(x: A): Unit =
    elements = elements.prepended(x)
  def peek: A = elements.head
  def pop(): A = {
    val currentTop = peek
    elements = elements.tail
    currentTop
  }
}
// здесь мы объявляем параметр типа A
//          v
class Stack[A]:
  private var elements: List[A] = Nil
  //                         ^
  //  здесь мы ссылаемся на этот тип
  //          v
  def push(x: A): Unit =
    elements = elements.prepended(x)
  def peek: A = elements.head
  def pop(): A =
    val currentTop = peek
    elements = elements.tail
    currentTop

Эта реализация класса Stack принимает любой тип в качестве параметра. Прелесть параметризованных типов состоит в том, что теперь можно создавать Stack[Int], Stack[String] и т.д., что позволяет повторно использовать реализацию Stack для произвольных типов элементов.

Пример создания и использования Stack[Int]:

val stack = new Stack[Int]
stack.push(1)
stack.push(2)
println(stack.pop())  // выводит 2
println(stack.pop())  // выводит 1
val stack = Stack[Int]
stack.push(1)
stack.push(2)
println(stack.pop())  // выводит 2
println(stack.pop())  // выводит 1

Подробности о том, как выразить вариантность с помощью универсальных типов, см. в разделе “Вариантность”.

Contributors to this page: