I am trying to use pattern matching on a List of objects. The method takes in queue: List[ScheduleChangeEvent]
. ScheduleChangeEvent
is a sealed trait
with 4 different final case class
's. Therefore, depending on what type of ScheduleChangeEvent
the list contains, I need to do something different.
I implemented the following:
queue match {
case lsc: List[LocationSettingsChange] =>
...
case lwhc: List[LocationWorkHoursChange] =>
...
case tpc: List[TeamParameterChange] =>
...
case mptc: List[MemberPrimaryTeamChange] =>
...
}
However, I get the warning unreachable code [warn] case tpc: List[LocationWorkHoursChange] =>
. And no matter what the incoming queue is, it always goes to case lac
. I understand what the warning is, but I cannot understand why I am getting it.
This is because in runtime you have erasure. This means that jvm don't have type parameter values for generics. I.e. instead of List[LocationSettingsChange]
or List[LocationWorkHoursChange]
you have just List
in runtime. thing you can do with non-empty list is an introspection of kind case head :: tail if head.isInstanceOf[LocationSettingsChange]
or with extractor if you have one.
Generally try to avoid situations where you should do this, and if you can do something like that by passing pattern matching from list to element of list:
list.map {
case x: LocationSettingsChange => ???
case x: LocationWorkHoursChange=> ???
case x: TeamParameterChange=> ???
case x: MemberPrimaryTeamChange=> ???
}
By doing this you won't have any problems with erasure, but if you still need this you can use type tags and match on them at cost of runtime performance penalty, more of this described here: https://docs.scala-lang.org/overviews/reflection/typetags-manifests.html