避免使用类型成员和子类型转换的强制类型转换

5
我在路径依赖类型和模式匹配方面遇到了问题:
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]])

当然,肯定有一种干净的方法可以避免强制转换吧?

我不确定,但是这种类型转换不是违背了路径相关类型的逻辑吗?那为什么不使用具有协变性的类型投影呢? - 4lex1v
我无法使用投影,因为基本成员类型太普遍了。只有通过 trait Foo[F <: Foo[F]] { type Bar; def defaultBar: F#Bar } 的方式才能实现,但我真的想避免这种情况。 - 0__
你是否缺少了 Baz 的一些代码?在上面的示例中,您从未将 Baz 定义为 Bar 的类型。您的测试是匹配 Foo,但您的代码从未使 Baz 成为有效的 Foo - iain
@iain BazFoo 的子类型。如果我匹配到 foo 并发现它是 Baz 的实例,显然 b eq foo - 0__
1个回答

0

如果不使用投影和将类型限制为defaultBar,则无法实现。

例如:

trait MyFoo extends Foo { override def defaultBar: Int }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接