scala - Pattern match on manifest instances of sealed class -
given classes
sealed abstract class case class b(param: string) extends case class c(param: int) extends trait z {} class z1 extends z {} class z2 extends z {} def zfor[t <: : manifest]: option[z] = { val z = manifest[t].erasure if (z == classof[b]) { some(new z1) } else if (z == classof[c]) { some(new z2) } else { none } }
i think problem pattern matching here impossibility build pattern matching table in bytecode. there workaround on problem? may can use int generated in manifest compiler?
the way you've written there isn't robust if have more complicated class hierarchy since if have class d <: c
, classof[d] != classof[c]
. don't want pattern-match anyway. could; can't call classof[x]
in middle of pattern-match, can
def zfor[t <: : manifest]: option[z] = { val classb = classof[b] val classc = classof[c] manifest[t].erasure match { case classb => some(new z1) case classc => some(new z2) case _ => none } }
as long you're sure you're in situation need detect leaves of class hierarchy. (you should make sure marking b
, c
final
.)
alternatively, can use isassignablefrom
perform runtime test:
def zfor2[t <: : manifest]: option[z] = { manifest[t].erasure match { case x if classof[b].isassignablefrom(x) => some(new z1) case x if classof[c].isassignablefrom(x) => some(new z2) case _ => none } }
and now
class d extends c(5) {} scala> zfor[d] res5: option[z] = none scala> zfor2[d] res6: option[z] = some(z2@2556af33)
Comments
Post a Comment