我(有点)了解Scala类型系统的基础知识,但还不够好!为什么以下两个函数的返回类型不等同?
trait Base[T]
case class Foo() extends Base[Foo]
case class Bar() extends Base[Bar]
def willNotCompile[T <: Base[_]](x: Int): T =
if(x < 10) new Foo() else new Bar()
def compilesFine(x: Int): Base[_] =
if(x < 10) new Foo() else new Bar()
Run Code Online (Sandbox Code Playgroud)
第一个函数的类型表明,对于所有人都 T
选择的(只要它们是子类型Base
),函数必须返回该类型的值T
.后一个函数不承诺任何类似的东西,它只返回类型Base
.(我实际上并不认为类型参数与Base
此示例相关.)
例如,考虑我定义:
case class Baz() extends Base[Baz]
Run Code Online (Sandbox Code Playgroud)
然后类型willNotCompile
允许我打电话
willNotCompile[Baz](0)
Run Code Online (Sandbox Code Playgroud)
我应该回到类型的值Baz
!显然,情况并非如此,因此定义不进行类型检查.
另一个函数没有声明返回任何更具体类型的东西Base
,所以没有问题.
FWIW,这个例子表明参数多态(又名"泛型")比仅仅的子类型更具表现力.