Scala泛型

时间:2023-03-30 22:10:04

目录

1 协变和逆变

2 泛型上下限

3 上下文限定


1 协变和逆变

        Scala中的协变和逆变是解决类型转换问题的机制,它们与Scala的泛型类型参数有关。在Scala中,协变和逆变可以通过在类型参数前面添加"+"和"-"符号来实现。

        协变表示类型参数能够被隐式地转换为更具体的类型,例如,如果B是A的子类型,则List[B]是List[A]的子类型。这可以通过在类型参数前面添加"+"符号来实现,例如:

class Animal
class Cat extends Animal

class Container[+A](val elem: A)

val catContainer: Container[Cat] = new Container[Cat](new Cat)
val animalContainer: Container[Animal] = catContainer // 协变

        这里,Container[Cat]是Container[Animal]的子类型,因为Cat是Animal的子类型。因此,我们可以将catContainer赋值给animalContainer。

        相反,逆变表示类型参数能够被隐式地转换为更一般的类型,例如,如果B是A的子类型,则Comparator[A]是Comparator[B]的子类型。这可以通过在类型参数前面添加"-"符号来实现,例如:

 

class Animal
class Cat extends Animal

class Comparator[-A] {
  def compare(a1: A, a2: A): Int = ???
}

val catComparator: Comparator[Cat] = new Comparator[Animal]

        这里,Comparator[Animal]是Comparator[Cat]的子类型,因为Animal是Cat的父类型。因此,我们可以将catComparator赋值给animalComparator。

2 泛型上下限

        Scala的泛型类型参数还支持上下限限定,它们可以用来限制类型参数的范围。上限类型限定表示类型参数必须是某个类型的子类型下限类型限定表示类型参数必须是某个类型的父类型

例如,我们可以定义一个接受某个类型的List并返回该类型的最大值的方法,该类型必须是Comparable类型的子类型:

def max[T <: Comparable[T]](a: T, b: T): T = {
  if (a.compareTo(b) < 0) b else a
}

val maxInt = max(3, 5) // 5
val maxString = max("hello", "world") // world

这里,"<: Comparable[T]"表示类型参数T必须是Comparable[T]的子类型,因此我们可以调用max方法并传递Int和String类型的参数。

3 上下文限定

        上下文限定是另一种类型约束,它使用implicit关键字和隐式参数来实现。上下文限定通常用于需要某个类型的隐式值的方法或类中。

例如,我们可以定义一个需要一个类型为Ordering[T]的隐式值的方法,该方法接受两个类型为T的参数并返回较小的那个:

def min[T](a: T, b: T)(implicit ord: Ordering[T]): T = {
  if (ord.compare(a, b) < 0) a else b
}

val minInt = min