【发布时间】:2019-08-06 18:44:07
【问题描述】:
我尝试在不使用 scala.reflect.ClassTag 的情况下在 Scala 中进行集合匹配
case class Foo(name: String)
case class Bar(id: Int)
case class Items(items: Vector[AnyRef])
val foo = Vector(Foo("a"), Foo("b"), Foo("c"))
val bar = Vector(Bar(1), Bar(2), Bar(3))
val fc = Items(foo)
val bc = Items(bar)
我们不能这样做:
fc match {
case Items(x) if x.isInstanceOf[Vector[Foo]]
}
因为:
警告:scala.collection.immutable.Vector[Foo](Vector[Foo] 的底层)中的非变量类型参数 Foo 未检查,因为它已被擦除消除
还有这个:
fc match {
case Items(x: Vector[Foo]) =>
}
但我们可以这样做:
fc match {
case Items(x@(_: Foo) +: _) => ...
case Items(x@(_: Bar) +: _) => ...
}
bc match {
case Items(x@(_: Foo) +: _) => ...
case Items(x@(_: Bar) +: _) => ...
}
如您所见,我们正在检查 - 是集合 Foo + 矢量还是 Bar + 矢量。
我们遇到了一些问题:
- 我们可以做 Vector(Foo("1"), Bar(2)),这将与 Foo 匹配。
- 我们仍然需要 "val result = x.asInstanceOf[Vector[Bar]]" 类转换来提取结果
还有什么更漂亮的方式吗? 像这样:
fc match {
case Items(x: Vector[Foo]) => // result is type of Vector[Foo] already
}
【问题讨论】:
-
只需使用
ClassTag...“Off topic”部分应该有一个“XY-problem”子部分。
标签: scala generics pattern-matching scala-collections