我想对通用参数进行模式匹配。我写了以下示例:
<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
。也许有一些解决方法可以针对类型参数进行模式匹配?
答案 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
。