scala - 从 String 创建 typeTag 并将其传递给多态方法

标签 scala generics reflection

我有一个多态方法,它将自定义案例类作为类型参数。 现在,为了支持多个案例类(在配置文件中定义为字符串),我需要将字符串转换为案例类的 tagType

为此,我使用 runtimeMirror 方法从 String 中获取类, 然后我使用 manifestToTypeTag 获取 tagType ( Getting TypeTag from a classname string )

import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe
import scala.reflect.ManifestFactory

// My polymorphic method
def printMe[T](l: List[T])(implicit typeTag: TypeTag[T]): Unit = println(l)

// This works:
printMe(List("fdfg"))(typeTag[java.lang.String])

// Now, I want to build the typeTag dynamically from a String
val className = "java.lang.String" // a Custom case class 
val mirror = universe.runtimeMirror(getClass.getClassLoader)
val cls = Class.forName(className)
// Getting the typeTag from the class name
val t = internal.manifestToTypeTag(mirror,ManifestFactory.classType(cls))

// Call of the method with the generated typeTag
printMe(List("fdfg"))(t)

// Compilation error
Error:(12, 31) type mismatch;
found   : scala.reflect.api.Universe#TypeTag[Nothing]
required: reflect.runtime.universe.TypeTag[String]
Note: Nothing <: String, but trait TypeTag is invariant in type T.
You may wish to investigate a wildcard type such as `_ <: String`. (SLS 3.2.10)
printMe(List("fdfg"))(t)

但是,当我将 typeTag 传递到我的多态方法时,出现了如上所示的“类型匹配编译错误”。 实际上,我的多态方法需要 TypeTag[MyClassToto],而我生成的 TypeTagTypeTag[Nothing]

我想知道是否可以转换我得到的 TypeTag,或者我可能必须更改我的多态方法的签名?

最佳答案

尝试来自 https://stackoverflow.com/a/23792152/5205022 的建议:

def printMe[T](l: List[T])(implicit typeTag: TypeTag[T]): Unit = println(l)

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.")
  })
}

printMe(List("fdfg"))(stringToTypeTag("java.lang.String"))

关于scala - 从 String 创建 typeTag 并将其传递给多态方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56649872/

相关文章:

java - 如何使用 Java 泛型将 "T"参数作为方法参数传递?

c# - 在 C# 中将类成员引用为枚举

reflection - 使用反射检查分配给 interface{} 变量的函数签名

scala - 如何迭代记录 Spark Scala?

scala - 如何在 sbt 中运行和编译精确的一个测试?

scala - 无法使用 scala 的 sbt 从存储库中获取插件

function - 如何在 Rust 中找到函数调用者的类型?

scala - Scala方法类型和方法作为参数

C# 将 List<int> 转换为 List<double>

swift - 在 Swift 中使用 where 子句扩展数组类型