0

我正在寻找一种将作为字符串给出的 Scala 单例对象(例如:package1.Main)转换为 Main 的实际实例的方法,以便我可以在其上调用方法。

问题示例:

package x {
  object Main extends App {
    val objectPath: String = io.StdIn.readLine("Give an object: ") // user enters: x.B

    // how to convert the objectPath (String) to a variable that references singleton B?
    val b1: A = magicallyConvert1(objectPath)
    b1.hi()

    val b2: B.type = magicallyConvert2(objectPath)
    b2.extra()
  }

  trait A {
    def hi() = {}
  }

  object B extends A {
    def extra() = {}
  }
}

magiclyConvert1 和magicallyConvert2 函数如何实现?

4

2 回答 2

1

对于普通课程,可以使用以下方法完成:

val b: A = Class.forName("x.B").newInstance().asInstanceOf[A]

但我找到了一个使用 Java 反射的单例解决方案:

在 Java 中可以通过以下名称访问单例:package.SingletonName$.MODULE$ 所以您必须附加“$.MODULE$”,这是一个静态字段。所以我们可以使用标准的Java反射来获取它。

所以解决方案是:

def magicallyConvert1(objectPath: String) = {
  val clz = Class.forName(objectPath + "$")
  val field = clz.getField("MODULE$")
  val b: A = field.get(null).asInstanceOf[A]
  b
}

def magicallyConvert2(objectPath: String) = {
  val clz = Class.forName(objectPath + "$")
  val field = clz.getField("MODULE$")
  val b: B.type = field.get(null).asInstanceOf[B.type]
  b
}

但是看到 Scala-Reflect en Scala-Meta 的解决方案仍然会很有趣。

于 2017-03-08T16:45:20.707 回答
0

看看 scalameta http://scalameta.org它可以满足您的需求以及更多

于 2017-03-08T03:46:48.220 回答