Reputation: 198178
I'm trying to filter a list by the type of items. The working code is here:
trait Action
class AAA extends Action
class BBB extends Action
val list = List(new AAA, new BBB, new AAA)
def find[T <: Action] = list.filter(_.isInstanceOf[T])
find[AAA]
It doesn't work as expected, see the output:
scala> def find[T <: Action] = list.filter(_.isInstanceOf[T])
<console>:11: warning: abstract type T is unchecked since it is eliminated by erasure
def find[T <: Action] = list.filter(_.isInstanceOf[T])
^
find: [T <: Action]=> List[Action]
scala> find[AAA]
res0: List[Action] = List(AAA@2b9cbeec, BBB@3fba8e52, AAA@70d5ca2d)
How to fix it?
Upvotes: 1
Views: 205
Reputation: 1
use implicit m:scala.reflect.Manifest[T]
def find[T <: Action](implicit m:scala.reflect.Manifest[T]) =
list.filter{x:Any => m.erasure.isInstance(x)}.asInstanceOf[List[T]]
Upvotes: 0
Reputation: 38045
You could use ClassTag
:
def find[T <: Action : ClassTag] =
list.filter{ implicitly[ClassTag[T]].runtimeClass.isInstance }
scala> find[AAA]
res0: List[Action] = List(AAA@145332ca, AAA@135cfef8)
It would be better to use collect
method:
list.collect{ case e: AAA => e }
Upvotes: 2