如何避免scala中类型约束的重复

时间:2018-03-19 14:14:54

标签: scala types

我经常在Scala中遇到以下问题:

给出一个特质

trait Foo { def foo: String }

和参数化类

case class Bar[T <: Foo](t: T)

我想编写一个与Bar一起使用的方法而不重复类型约束,例如:

def doSth(bar: Bar[_]) = bar.t.foo

不幸的是,它没有编译,我需要写:

def doSth[T <: Foo](bar: Bar[T]) = bar.t.foo

为什么编译器无法推断如果我有Bar[_]_必须是Foo

是否有解决方法(抽象类型会避免重复,但会增加表示某些约束的复杂性)?

1 个答案:

答案 0 :(得分:2)

似乎

def doSth(bar: Bar[_]) = bar.t.foo

基本相同
def doSth0(bar: Bar[X] forSome { type X }) = bar.t.foo

type X完全不受约束。因此,我认为这个问题应该是:

为什么编译器完全允许Bar[X] forSome { type X }之类的东西,即使X未被声明为Foo的子类型,而Bar需要参数是Foo的子类型?

我不知道答案。可能它再次与java泛型有关。

<强>变通方法

鉴于特质和阶级

trait Foo { def foo: String }
case class Bar[T <: Foo](t: T)

以下两个定义在没有其他类型参数的情况下工作:

def doSth1(bar: Bar[X] forSome { type X <: Foo }) = bar.t.foo
def doSth2(bar: Bar[_ <: Foo]) = bar.t.foo

另一种选择是约束t本身Bar的类型:

case class Bar2[T <: Foo](t: T with Foo)
def doSth3(bar: Bar2[_]) = bar.t.foo