【发布时间】:2012-06-27 14:42:32
【问题描述】:
通常,当收集与特定类型匹配的序列的所有元素时,生成的集合既有原始集合的类型,也有为以下选择的类型:
trait Foo
trait Bar
trait Baz {
// Works
def def1(foo: Seq[Foo]): Seq[Foo with Bar] =
foo collect {case foobar: Bar => foobar}
}
当输入类型由有界成员类型参数化并且我想要返回的只是由绑定类型(不是成员类型)参数化的序列时,这甚至可以工作:
trait Baz {
type memberType <: Foo
// Works
def2(foo: Seq[memberType]): Seq[Foo with Bar] =
foo collect {case foobar: Bar => foobar}
}
但是,当我实际上想要返回由成员类型参数化的序列时,这会失败:
trait Baz {
type memberType <: Foo
// Fails
def def3(foo: Seq[memberType]): Seq[memberType with Bar] =
foo collect {case foobar: Bar => foobar}
}
错误信息:
error: type mismatch;
found : Seq[this.Foo with this.Bar]
required: Seq[Baz.this.memberType with this.Bar]
foo collect {case foobar: Bar => foobar}
为了恢复功能,我可以在 collect 调用中包含成员类型,但鉴于签名的原因,每个元素都必须匹配该类型,这似乎是多余的:
trait Baz {
type memberType <: Foo
// Works
def def4(foo: Seq[memberType]): Seq[memberType with Bar] =
foo collect {case foobar: memberType with Bar => foobar}
}
有没有办法定义成员类型的序列,以便他们在collected 时记住他们的成员类型?
【问题讨论】:
-
已检查该代码是否有警告?由于
memberType是抽象的,它在foobar: memberType with Bar检查中被删除。 -
我有点困惑为什么 1 和 2 甚至可以工作。收集的序列只是一个 Seq[Bar],但编译器仍然允许将其键入为 Seq[Foo with Bar]。好吧,我想我更困惑为什么这不会导致擦除警告。
-
我在运行任何工作示例时都没有看到任何警告。类型擦除会对最后一个示例产生任何影响(已对其进行编辑以正确指示它“有效”)?
-
这很奇怪,但如果你把 Baz 变成一个类,它确实会显示警告。
标签: scala type-inference type-parameter partialfunction