Scala如何将Object类型传递给类型参数?

时间:2017-04-06 10:52:02

标签: scala

我已经定义了这样的类:

class Counta [T : TypeTag] {
--cutted--
}

我需要在运行时使用正确的类型实例化此类。 我有在运行时创建正确类型的对象的函数:

  def ConvertSparkTypesToScala(dataType: DataType) = {
    dataType match {
      case IntegerType => Int
      case BooleanType => Boolean
      case FloatType => Float
      case DoubleType => Double
      case LongType => Long
      case ByteType => Byte
      case ShortType => Short
    }
  }

现在,当我尝试像这样实例化类时:

      val scalaType = ConvertSparkTypesToScala(dt)
      println(scalaType)
      val countA = new Counta[scalaType.type]
      println(scalaType)

我得到例外,只有第一张println打印:

  

对象scala.Int

然后我得到了例外:

  

java.lang.UnsupportedOperationException:类型的架构   不支持scalaType.type

所以基本上这并不像你在代码中写入类型一样。 所以问题是,我想做的是什么?如果是这样,如何实现这一目标?

1 个答案:

答案 0 :(得分:1)

也许你可以尝试这些方面的东西。但我猜你所做的事情并没有多大意义,因为这可能是XY problem

import scala.reflect.runtime.universe._

def ConvertSparkTypesToScala(dataType: DataType): TypeTag[_] = {
  dataType match {
    case IntegerType => typeTag[Int]
    case BooleanType => typeTag[Boolean]
    case FloatType => typeTag[Float]
    case DoubleType => typeTag[Double]
    case LongType => typeTag[Long]
    case ByteType => typeTag[Byte]
    case ShortType => typeTag[Short]
  }
}

val dt: DataType = LongType
val scalaTag = ConvertSparkTypesToScala(dt)
println(scalaTag)
val countA = new Counta()(scalaTag)

countA现在具有存在类型Counta[_],这意味着如果Counta包含采用T或生成T的方法,则这些方法非常漂亮现在没用了,因为编译器不知道T究竟是什么。

您尝试做的是在ConvertSparkTypesToScala方法中在运行时计算信息,然后在编译时使用该信息告诉编译器类型countA是什么。您将始终在程序运行之前编译它,因此信息不可能从运行时流向编译时。

如果您希望根据countA

计算dt的类型
  1. 您需要在编译时计算它(带有implicits或宏或......)和
  2. 需要在编译时知道精确类型dt;意味着dt的类型必须是LongType.typeIntegerType.type,而不仅仅是DataType