在Scala中使用反射类概念时遇到的问题

问题描述

我有一个这样的主班:

class Test {
  def exe(first:String,second:String,task:String):String = {
     task match {
       case "A" => {
          val obj = new A(first)
          obj.definesecond(second)
       }
       case "B" => {
          val obj = new B(first)
          obj.definesecond(second)
       }
       case "C" => {
          val obj = new C(first)
          obj.definesecond(second)
       }
       ....so many cases
   }
 }
}

我没有在每次添加新类时在Test类中编写案例,而是尝试在scala中使用反射的概念。 以下是我的尝试:

val m = ru.runtimeMirror(getClass.getClassLoader)
val classtest = ru.typeOf[Test].typeSymbol.asClass
val cm = m.reflectClass(classtest)

但是由于“类测试是内部类,请在InstaneMirror上使用reflectClass获取其类镜像”而得到错误

谁能知道我该如何避免在每次创建新类时都向我的主类中添加案例,而是可以以一种适用于每种情况的方式编写主类。

解决方法

我想您尚未提供所有必要的信息。在错误消息中写道“类Test是内部类”,但是代码段中Test不是内部类。如果您希望固定运行时反射代码,请提供反映实际用例的代码段。

与此同时,您可以尝试macro(在编译时工作)

import scala.language.experimental.macros
import scala.reflect.macros.blackbox

class Test {
  def exe(first: String,second: String,task: String): String = macro Test.exeImpl
}

object Test {
  def exeImpl(c: blackbox.Context)(first: c.Tree,second: c.Tree,task: c.Tree): c.Tree = {
    import c.universe._
    val cases = Seq("A","B","C").map(name =>
      cq"""${Literal(Constant(name))} => {
        val obj = new ${TypeName(name)}($first)
        obj.defineSecond($second)
      }"""
    )
    q"$task match { case ..$cases }"
  }
}

用法:

class A(s: String) {
  def defineSecond(s1: String): String = ""
}
class B(s: String) {
  def defineSecond(s1: String): String = ""
}
class C(s: String) {
  def defineSecond(s1: String): String = ""
}

new Test().exe("first","second","task")

//scalac: "task" match {
//  case "A" => {
//    val obj = new A("first");
//    obj.defineSecond("second")
//  }
//  case "B" => {
//    val obj = new B("first");
//    obj.defineSecond("second")
//  }
//  case "C" => {
//    val obj = new C("first");
//    obj.defineSecond("second")
//  }
//}