简体   繁体   中英

Instance case class from companion object

I have the following:

trait C {}

object O {
    case class Foo(bar: String) extends C
}

And I would like to instance Foo from a String. Until the moment I have achieved instanciate Foo, but I cannot cast to C. I am using:

val ob = runtimeMirror.staticModule("O.Foo")
val foo = runtimeMirror.reflectModule(ob).instance

Now foo is an instance of O.Foo, but it cannot be cast to C.

val c = foo.asInstanceOf[C] 

This very last line returns:

O$foo$ cannot be cast to C

The solution was much easier than I have ever thought.

Class.forName("O$Foo").newInstance

It should be noted that with this solution requires that Foo has a constructor without args. This last condition is not a problem for my code, so it is solved.

Case classes extending a trait will implement only in their class, not in their companion object for example see:

trait C {}

object O {
  case class Foo(bar: String) extends C
  case class Foo2(bar: String) extends C
  object Foo2 extends C
}

object Q extends App {
  import scala.reflect.runtime.universe._
  val rm = runtimeMirror(getClass.getClassLoader)

  for (ref <- Seq("O.Foo", "O.Foo2")) {
    val ob = rm.staticModule(ref)
    val foo = rm.reflectModule(ob).instance
    println(foo.isInstanceOf[C])
  }
}

This prints:

false

true

When you are referring to the staticModule s, you are referring to the companion objects, that is why C is not implemented by the class you were testing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM