[英]Conditional type variable in Scala
我试图在条件式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反射文档,我发现了一些方法。 但是,我在玩tq
。
我遇到的主要问题是如何在运行时定义类型变量type In
。
我删除了先前的答案,因为它实际上并未回答上述问题。 由于问题中的评论,我得出了适用于我的情况的以下解决方案。
问题是类型不能在运行时生成,只能在编译类型时生成。 因此,我必须为每个输入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)
}
先前的代码执行的是:
您是否正在寻找类似的东西?
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]")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.