Scala 游览

泛型类

语言

泛型类是将类型作为参数的类。它们对于集合类特别有用。

定义泛型类

泛型类在方括号 [] 中将类型作为参数。一种约定是使用字母 A 作为类型参数标识符,尽管可以使用任何参数名称。

class Stack[A] {
  private var elements: List[A] = Nil
  def push(x: A): Unit =
    elements = x :: elements
  def peek: A = elements.head
  def pop(): A = {
    val currentTop = peek
    elements = elements.tail
    currentTop
  }
}
class Stack[A]:
  private var elements: List[A] = Nil
  def push(x: A): Unit =
    elements = x :: elements
  def peek: A = elements.head
  def pop(): A =
    val currentTop = peek
    elements = elements.tail
    currentTop

Stack 类的实现将任何类型 A 作为参数。这意味着底层列表 var elements: List[A] = Nil 只能存储类型 A 的元素。过程 def push 只接受类型 A 的对象(注意:elements = x :: elementselements 重新分配给一个新列表,该列表通过将 x 前置到当前 elements 来创建)。

此处的 Nil 是一个空的 List,不要与 null 混淆。

用法

要使用泛型类,请将类型放在方括号中,代替 A

val stack = new Stack[Int]
stack.push(1)
stack.push(2)
println(stack.pop())  // prints 2
println(stack.pop())  // prints 1
val stack = Stack[Int]
stack.push(1)
stack.push(2)
println(stack.pop())  // prints 2
println(stack.pop())  // prints 1

实例 stack 只能采用 Int。但是,如果类型参数具有子类型,则可以传入子类型

class Fruit
class Apple extends Fruit
class Banana extends Fruit

val stack = new Stack[Fruit]
val apple = new Apple
val banana = new Banana

stack.push(apple)
stack.push(banana)
class Fruit
class Apple extends Fruit
class Banana extends Fruit

val stack = Stack[Fruit]
val apple = Apple()
val banana = Banana()

stack.push(apple)
stack.push(banana)

AppleBanana 均扩展 Fruit,因此我们可以将实例 applebanana 推送到 Fruit 的堆栈中。

注意:泛型类型的子类型是 *不变的*。这意味着,如果我们具有类型为 Stack[Char] 的字符堆栈,则不能将其用作类型为 Stack[Int] 的整数堆栈。这将是不合理的,因为它会使我们能够在字符堆栈中输入真正的整数。总之,仅当且仅当 B = A 时,Stack[A] 才为 Stack[B] 的子类型。由于这可能相当具有限制性,因此 Scala 提供了一个 类型参数注释机制 来控制泛型类型的子类型行为。

此页面的贡献者