是否有解决类型擦除的方法?

时间:2018-09-24 14:11:14

标签: scala pattern-matching type-parameter

我想对通用参数进行模式匹配。我写了以下示例:

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.css">

<style>
  body {
    padding-bottom: 30px;
  }
  h1, h2, p {
    font-family: sans-serif;
    text-align: center;
  }
  .leaflet-container {
    height: 400px;
    width: 80%;
    margin: 0 auto;
  }
</style>

我了解到new Cls().processA("") //prints B: C sealed trait Tr[A, B <: A, C <: A]{ def getA(str: String): A final def processA(str: String): Unit = getA(str) match { case b: B => println(s"B: " + b) case c: C => println(s"C: " + c) } } sealed trait A final case class B() extends A final case class C() extends A final class Cls extends Tr[A, B, C] { override def getA(str: String): A = C() } B参数被擦除到它们的下限C。也许有一些解决方法可以针对类型参数进行模式匹配?

2 个答案:

答案 0 :(得分:4)

您可以使用ClassTag,以便可以在运行时进行检查。

import scala.reflect.ClassTag

sealed abstract class Tr[A, B <: A : ClassTag, C <: A : ClassTag]{
  def getA(str: String): A

  final def processA(str: String): Unit = getA(str) match {
    case b: B => println(s"B: " + b)
    case c: C => println(s"C: " + c)
  }
}

为此,您需要用抽象类替换trait,因为trait不能具有带有上下文边界的类型参数。

答案 1 :(得分:2)

对于这种情况,是的,有:添加import scala.reflect.ClassTag并将Tr的定义更改为

sealed abstract class Tr[A, B <: A : ClassTag, C <: A : ClassTag]

请注意,这不会影响is/asInstanceOf