我试图在条件if-else之后在Scala中定义变量“类型”。
目的是获得像type In = xxx
这样的变量。这样就可以实例化参数化的类或调用参数化的函数。给出定义:
class MyParamClass[T: TypeTag](context: String){...}
def startStrean[T: TypeTag](context: String) = {...}
我想创建一个MyParamClass[T](context = "my contentx")
的实例,其中T取决于配置字符串。用户可以使用API提供配置字符串。
val conf = Option("Map[String, Any]")
//get the data types from the context
type In = conf match {
case Some("Map[String, Int]") => Map[String, Int]
case Some("Map[String, Double]") => Map[String, Double]
case Some("List[Double]") => List[Double]
case Some("List[Int]") => List[Int]
case None => Map[String, Any]
}
注意:先前的代码段无法编译。
然后,创建类或执行函数:
val context = "my context"
val pc = new MyParamClass[In](context)
startStream[In](context)
请注意,类型T
不能从参数类型中推断出来。
看着Scala reflection documentation,我看到了一些方法。但是,我在玩tq
。
我遇到的主要问题是如何在运行时定义类型变量type In
。
答案 0 :(得分:0)
我删除了先前的答案,因为它实际上并未回答上述问题。多亏了问题中的评论,我得出了适用于我的情况的以下解决方案。
问题在于类型不能在运行时生成,只能在编译类型时生成。因此,我必须为每个输入conf
字符串编写调用。
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox
val mirror = runtimeMirror(getClass.getClassLoader)
val tb = mirror.mkToolBox()
def typecheckType(tree: Tree): Type = tb.typecheck(tree, tb.TYPEmode).tpe
typecheckType(tq"$context") match {
case tpe if tpe =:= typeOf[Map[String, _]] =>
startStrean[Map[String, Any], Map[String, Any]](context = context)
case tpe if tpe =:= typeOf[Map[String, Double]] =>
startStrean[Map[String, Double], Map[String, Double]](context = context)
case tpe if tpe =:= typeOf[Map[String, Int]] =>
startStrean[Map[String, Int], Map[String, Int]](context = context)
case tpe if tpe =:= typeOf[List[Double]] =>
startStrean[List[Double], List[Double]](context = context)
case tpe if tpe =:= typeOf[String] =>
startStrean[String, String](context = context)
case tpe if tpe =:= typeOf[Int] =>
startStrean[Int, Int](context = context)
case tpe if tpe =:= typeOf[Double] =>
startStrean[Double, Double](context = context)
case _ =>
startStrean[Map[String, Any], Map[String, Any]](context = context)
}
上一个代码的作用是:
答案 1 :(得分:0)
您是否正在寻找类似的东西?
class MyParamClass[T](context: String) {
def apply() {
context match {
case "Map[String, Int]" => new MyParamClass[Map[String, Int]](context)
case "Map[String, Double]" => new MyParamClass[Map[String, Double]](context)
case _ => new MyParamClass[Map[String, Any]](context)
}
}
}
然后您可以输入键入的类:val clazz: MyParamClass[_] = new MyParamClass("Map[String, Long]")