Scala 上限符号接受所有类型不仅是超类型

问题描述

在 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 petAnimal。如果它使用 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 的子类型。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...