Scala 上界表示法接受所有类型(不仅是超类型)

Scala upper bound notation accepts all types (not only super type)

在Scala的上界概念中,可以传递给定类型或其超类型。例如,在下面的方法中,S 是类型,A 是我们传递的参数。该方法实际上接受 Scala 类型系统中存在的所有值。 S、S 子类型及其超类型。这是因为所有类型都扩展了 Any 类型。

def method[A >: S](a:A) = { ... }

那为什么我们不能把所有的上界记号都写成Any(这是Scala中的通用类型)。上面的定义可以重写为:

def met(a:Any) = { ... }

这个很容易理解。

上界有什么优势?

谢谢!

Any 相比,它可以让您丢失更少的类型信息。

例如,如果您让 Dog 和 Cat 继承 Animal,则此方法有效:

val maybeDog: Option[Dog] = ???

val pet = maybeDog.getOrElse(Cat())

因为getOrElse的签名为def getOrElse[B >: A](default: => B): B,推断BAnimal(作为Cat和Dog的最小上界),所以val pet 的静态类型是 Animal。如果它使用 Any,结果将需要不安全的转换才能进一步工作。如果它不完全引入新的类型参数,您将被迫编写 (maybeDog: Option[Animal]).getOrElse(Cat()) 以实现相同的统一。


此外,它限制实现不做完全愚蠢的事情。例如,这个类型检查:

def getOrElse[A](option: Option[A])(default: => Any): Any = 42 // Int is Any, so why not?

虽然这不是:

def getOrElse[A, B >: A](option: Option[A])(default: => B): B = 42 

因为虽然任何东西 都可以 变成 B,但这并不意味着 Int 总是 B 的子类型.