带有类型化参数的类上的Scala模式匹配

带有类型化参数的类上的Scala模式匹配,scala,generics,reflection,Scala,Generics,Reflection,我正在尝试对具有类型化参数的自定义类进行模式匹配: Foo类[A] def isMyFoo[A:ClassTag](v:Any)=v匹配{ 我的案例:Foo[A]=>“我的Foo” 案例其他:Foo[\u]=>“不是我的Foo” 案例u=>“不是foo” } 那是行不通的;无论Foo的类型是什么,我都会得到“我的Foo” 我能做出这样的作品的唯一方法是: class-Foo[A](隐式t:ClassTag[A]){ val标签=t } def isMyFoo[A:ClassTag](v:Any

我正在尝试对具有类型化参数的自定义类进行模式匹配:

Foo类[A]
def isMyFoo[A:ClassTag](v:Any)=v匹配{
我的案例:Foo[A]=>“我的Foo”
案例其他:Foo[\u]=>“不是我的Foo”
案例u=>“不是foo”
}
那是行不通的;无论
Foo的类型是什么
,我都会得到
“我的Foo”

我能做出这样的作品的唯一方法是:

class-Foo[A](隐式t:ClassTag[A]){
val标签=t
}
def isMyFoo[A:ClassTag](v:Any)=v匹配{
案例foo:foo[\u]=>
如果(foo.tag==classTag[A])“我的foo”
否则“不是我的福”
案例u=>“不是foo”
}
有没有更优雅的方式?我必须把
ClassTag
放在
Foo
里面吗

我必须把类标签放在Foo里面吗

对。
Foo
的类型参数在运行时被擦除,因此您所知道的就是您有一个
Foo[\u]
。唯一的解决方法是使用
ClassTag
TypeTag
保存类型信息。如果您打算这样做,我建议您使用
TypeTag
,因为您将能够使用更精细的类型
ClassTag
s仍然只能执行模式擦除

例如,使用
类标记
,这是错误的:

scala> val fooListString = new Foo[List[String]]
fooListString: Foo[List[String]] = Foo@f202d6d

scala> isMyFoo[List[Int]](fooListString)
res4: String = my foo
但以下措施将起作用:

class Foo[A](implicit t: TypeTag[A]) {
    val tag = t
}

def isMyFoo[A: TypeTag](v: Any) = v match {
    case foo: Foo[_] =>
        if (foo.tag.tpe =:= typeOf[A]) "my foo"
        else "not my foo"
    case _ => "not a foo"
}

scala> val fooListString = new Foo[List[String]]
fooListString: Foo[List[String]] = Foo@6af310c7

scala> isMyFoo[List[Int]](fooListString)
res5: String = not my foo