避免在Scala中安装的一种方法

避免在Scala中安装的一种方法,scala,generics,scala-collections,Scala,Generics,Scala Collections,我在Scala中有这样一个特性和类的层次结构: trait A trait B[T] extends A { def v: T } case class C(v:Int) extends B[Int] case class D(v:String) extends B[String] val l:List[A] = C(1) :: D("a") :: Nil l.foreach(t => println(t.asInstanceOf[B[_]].v)) 我无法更改类型层次结构或列表的类

我在Scala中有这样一个特性和类的层次结构:

trait A
trait B[T] extends A {
  def v: T
}
case class C(v:Int) extends B[Int]
case class D(v:String) extends B[String]
val l:List[A] = C(1) :: D("a") :: Nil
l.foreach(t => println(t.asInstanceOf[B[_]].v))
我无法更改类型层次结构或列表的类型


有没有更好的方法来避免[B[\u]]语句的asInstanceOf

您可以尝试模式匹配

l.collect{case x :B[_] => println(x.v)}

您可以尝试以下方法:

for (x <- l.view; y <- Some(x).collect { case b: B[_] => b }) println(y.v)


如果您可以将
l
的类型更改为
List[B[\u]]
,这将是一个更好的解决方案。

我认为最理想的方法是为
B
提供一个提取器对象,并为
B
值提供模式匹配:

对象B{
def unapply[T](参数:B[T]):Some[T]=Some(参数v)
}
l、 收集{案例B(x)=>println(x)}

如果源文件中声明了
B
,则无法更改,则可能需要为提取器对象使用不同的名称。

是否可以从一开始就将列表
l
声明为
list[B[\u]]]
,而不是显式声明为
list[a]
?如果无法更改列表的类型,您如何确定所有实例的类型都是
B
?如果任何实例的类型不是
B
,应如何处理?忽略它并继续?异常失败?我无法更改列表的类型。如果不是类型B,则忽略。如果列表不是实际的
list[B[\u]]]
,则会出现
MatchError
崩溃。确定。。。为什么你现在要收集无用的
()
-值列表?在我扔掉它们之前,我让我的猫玩弄它们。如果上升投票/unupvote是因为怀疑可反驳模式
b:b[\u]
是否可以在
for
中直接使用
来添加带有过滤器的
,步骤:显然它不能:
for(b:b[\uu]
for (x <- l) {
  x match {
    case b: B[_] => println(b.v)
    case _ => /* do nothing */
  }
}