简体   繁体   English

Scala-没有TypeTag可用当使用案例类尝试获取TypeTag时发生异常吗?

[英]Scala - No TypeTag Available Exception when using case class to try to get TypeTag?

I'm looking at the scala reflect API and I'm getting lots of exceptions. 我正在查看scala反映API,并且遇到了很多异常。

Doc reference: http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html 文档参考: http : //docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html

How do I get the typetag from a generic? 我如何从泛型获得类型标记?

  def getChildSettings[T: ru.TypeTag](path: String, settingsParameterObject: T) = {

    import scala.reflect.runtime.{ currentMirror => m }

    val m = ru.runtimeMirror(getClass.getClassLoader)
    val classC = ru.typeOf[T].typeSymbol.asClass
}

I get an exception: 我有一个例外:

No TypeTag available for ParameterObject.type

Even a very simple example doesn't seem to work (edit yes it does in the repl) 即使是一个非常简单的示例也似乎不起作用(编辑是,在repl中可以)

import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror
import scala.reflect.runtime.{universe => ru}

def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]

case class ParameterObject(stringType: String, optionType: Option[String])

getTypeTag(ParameterObject)

I'm guessing it's something about how I'm invoking the method. 我猜想这与我如何调用该方法有关。

I finally found out what the issue was. 我终于发现了问题所在。 The case classes must be defined top level - they cannot be nested. 案例类必须在顶层定义-它们不能嵌套。 Something like this would fail. 这样的事情会失败。

class Foo {
  describe("getSettings") {
    case class ParameterObject(foo: String)
    settings.getTypeTag(path, ParameterObject)
  }
}

class Clazzy {
      def getTypeTag[T: TypeTag](obj: T) = ru.typeTag[T]
}

If you need type tags for nested classes, you may use WeakTypeTag. 如果您需要嵌套类的类型标签,则可以使用WeakTypeTag。 I don't know why, but that's intentionally . 我不知道为什么,但这是有意的

Please declare Case class before you run main class 在运行主类之前,请先声明案例类

Example

case class Person(name: String, age: Long)

def main(args: Array[String]) {
   ...
    val people = sc.textFile("C:\\winutils\\people.txt").map(_.split(",")).map(p => Person(p(0), p(1).trim.toInt)).toDF()

You need a TypeTag at compile time, because that is the way to work around erasure: 您需要在编译时使用TypeTag ,因为这是解决擦除的方法:

import scala.reflect.runtime.{currentMirror => m, universe => ru}

def getChildSettings[T: TypeTag](path: String, settingsParameterObject: T) = {
  val tpe    = ru.typeOf[T]
  // val classC = tpe.typeSymbol.asClass
  val ctor   = tpe.declaration(ru.nme.CONSTRUCTOR).asMethod
  ...
}

The Scala Documentation Overview for Reflection gives an example of getting and invoking a constructor. 反射Scala文档概述给出了获取和调用构造函数的示例。

Add this code in your pom.xml 将此代码添加到pom.xml中

<dependency>
    <groupId>org.scala-lang</groupId>
    <artifactId>scala-reflect</artifactId>
    <version>2.12.0-M4</version>
</dependency>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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