首页 > 解决方案 > 具有类型成员的案例类的类型推断问题

问题描述

考虑以下示例:

sealed trait Kind

case object B extends Kind
case object C extends Kind

sealed trait Test {
  type K <: Kind
  val kind: K
}

object Test {
  type Aux[KK <: Kind] = Test { type K = KK }
}

sealed trait Suite{
  type K <: Kind
  val kind: K
  val tests: List[Test.Aux[K]]
}

def runSuite(suite: Suite): Unit = {
  suite.kind match {
    case _: B.type =>
      val tests: List[Test.Aux[B.type]] = suite.tests
      //
    case _: C.type =>
      val tests: List[Test.Aux[C.type]] = suite.tests
      //
  }
}

它看起来很自然,但无法编译:

Error:(47, 51) type mismatch;
 found   : List[Test.Aux[suite.K]]
    (which expands to)  List[Test{type K = suite.K}]
 required: List[Test.Aux[B.type]]
    (which expands to)  List[Test{type K = B.type}]
        val tests: List[Test.Aux[B.type]] = suite.tests
Error:(50, 51) type mismatch;
 found   : List[Test.Aux[suite.K]]
    (which expands to)  List[Test{type K = suite.K}]
 required: List[Test.Aux[C.type]]
    (which expands to)  List[Test{type K = C.type}]
        val tests: List[Test.Aux[C.type]] = suite.tests

我用asInstanceOf解决方法替换了它:

def runSuite(suite: Suite): Unit = {
  suite.kind match {
    case _: B.type =>
      val tests: List[Test.Aux[B.type]] = suite.tests.asInstanceOf[List[Test.Aux[B.type]]]
      //
    case _: C.type =>
      val tests: List[Test.Aux[C.type]] = suite.tests.asInstanceOf[List[Test.Aux[C.type]]]
      //
  }
}

它编译得很好。这里是asInstanceOf安全的,这只是Scala 2类型成员语义的另一个问题,还是背后有另一个原因?

标签: scalapattern-matchingtype-inferencetype-safetyaux-pattern

解决方案


推荐阅读