【发布时间】:2019-12-11 16:26:59
【问题描述】:
下面是一个示例。我需要将存储在 String 中的值转换为 Type 并将其传递给 scala 中的多态函数。
import scala.reflect.runtime.universe._
import scala.reflect.api
object Test {
def convert[T](l: String)(implicit typeTag: TypeTag[T]): T = l.asInstanceOf[T]
implicit def stringToTypeTag[A](name: String): TypeTag[A] = {
val c = Class.forName(name)
val mirror = runtimeMirror(c.getClassLoader)
val sym = mirror.staticClass(name)
val tpe = sym.selfType
TypeTag(mirror, new api.TypeCreator {
def apply[U <: api.Universe with Singleton](m: api.Mirror[U]) =
if (m eq mirror) tpe.asInstanceOf[U # Type]
else throw new IllegalArgumentException(s"Type tag defined in $mirror cannot be migrated to other mirrors.")
})
}
def main(args:Array[String]): Unit = {
val typ = "Integer"
val x = convert("10")(stringToTypeTag("java.lang." + typ))
val y = convert("20")(stringToTypeTag("java.lang." + typ))
println(x.getClass)
println(y.getClass)
val z = x + y
println(z)
// Expected OP 30
val typ = "String"
val x1 = convert("10")(stringToTypeTag("java.lang." + typ))
val y1 = convert("20")(stringToTypeTag("java.lang." + typ))
println(x1.getClass)
println(y1.getClass)
val z1 = x1 + y1
println(z1)
// Expected OP 1020
}
}
预期 OP:整数时为 30,字符串时为 1020
【问题讨论】:
-
问题到底是什么? - 但更重要的是,为什么?运行时反射极其困难且不安全,总体而言代码不会利用 Scala 的高级类型系统。因此,它的使用应仅限于绝对必要的情况。 - 如果你能分享你原来的问题,也许我们可以推荐一种不同的方法。
-
这是一个用于解释的示例。实际上我正在从配置文件加载各种参数,需要将值转换为从配置文件加载的类型。
-
你看过pureconfig吗?
-
这是我的完整场景 - args { runDate = { type = int, required = true } , schema = { type = String }。这是使用纯配置加载的。现在我打算使用现有的选项解析器 scpopt 或扇贝。要创建一个 argunemnt 选项,我需要调用 opt[String] 或 opt[Int],这个字符串 / int 来自配置,我需要将它们转换为类型,以便我可以将它们传递给这个函数和一个类型
-
我认为如果您关闭此问题并使用当前问题、示例输入、预期输出和您尝试过的所有代码打开一个新问题会更好。
标签: scala generics types polymorphism scala-reflect