避免使用类型成员和子类型进行类型转换

Avoid type cast with type member and sub-typing

提问人:0__ 提问时间:9/23/2013 更新时间:1/4/2014 访问量:230

问:

我在路径相关类型和模式匹配方面遇到了问题:

trait View[A]

trait Foo {
  type Bar

  def defaultBar: Bar
}
trait Baz extends Foo {
  def view(init: Bar): View[Bar]
}

trait Test {
  val foo: Foo

  def bar: foo.Bar = foo.defaultBar

  def test(): Option[View[foo.Bar]] =
    foo match {
      case b: Baz => Some(b.view(bar))
      case _ => None
    }
}

此操作失败,因为 scalac 不标识 .因此,它仅适用于两个强制转换:foob

      case b: Baz => Some(b.view(bar.asInstanceOf[b.Bar]).asInstanceOf[View[foo.Bar]])

肯定有一种干净的方法来避免石膏吗?

Scala 强制转换 路径相关 子类型

评论

0赞 4lex1v 9/23/2013
我不确定,但这种类型转换不是违背路径依赖类型的逻辑吗?那么为什么不使用协方差的类型投影呢?
0赞 0__ 9/23/2013
我不能使用投影,因为基本成员类型太笼统了。只有当我经历我真正想避免的箍时,这才会起作用。trait Foo[F <: Foo[F]] { type Bar; def defaultBar: F#Bar }
0赞 iain 9/23/2013
您是否缺少一些代码?在上面的此示例中,您从未将 定义为 的类型。您的测试在 上匹配,但您的代码永远不会产生有效的 .BazBazBarFooBazFoo
0赞 0__ 9/23/2013
@iain 是 的子类型。如果我匹配并发现它是 的实例,显然。BazFoofooBazb eq foo

答:

0赞 Akhil 1/4/2014 #1

如果不使用投影并限制类型,就不可能做到这一点,因为我们可以将其覆盖为不相关的数据类型defaultBar

例如

trait MyFoo extends Foo { override def defaultBar: Int }