在 scala 中有什么方法可以 return 一个类型吗?
Is there some way in scala that I can return a type?
我有很多class,例如DataFrameFlow
、TextFlow
、RDDFlow
。它们都派生自基数 class Flow
.
现在我想编写一个函数 judgeFlow
,它可以从 path: String
和 return 代表确切 Flow
类型的东西中读取,我可以从中创建相应的实例。整个代码如下
def judgeFlow(path:String) = /*1*/ {
Flow.getStoreType(path) match {
case StoreType.tdw =>
DataFrameFlow
case StoreType.hdfs =>
TextFlow
}
}
def createFlow(typeInfo:/*2*/) = /*3*/{
new typeInfo()
}
可是,1、2、3处我不知道怎么写
编辑
知道如何构建它们还不够,因为我还想要以下内容:
- 通过
typeInfo
进行模式匹配
- 一些方法
asInstanceOf
编辑 2
Flow
的定义
abstract class Flow(var outputName: String) extends Serializable{
def this() = this("")
...
}
DataFrameFlow
的定义
class DataFrameFlow(d: DataFrame, path: String) extends Flow {
var data: DataFrame = d
def this(data: DataFrame) = this(data, "")
def this(path: String) = this(null, path)
def this() = this(null, "")
...
}
模式匹配不能return 来自不同案例的不同类型。通过模式匹配 returned 的类型是 cases returned 类型的最小上限。
当有人想要 return 不同类型时,很可能 he/she 想要 class.
类型
sealed abstract class Flow
class DataFrameFlow extends Flow
class TextFlow extends Flow
class RDDFlow extends Flow
trait JudgeFlow[In] {
type Out <: Flow
def judgeFlow(in: In): Out
}
object JudgeFlow {
implicit val `case1`: JudgeFlow[???] { type Out = DataFrameFlow } = ???
implicit val `case2`: JudgeFlow[???] { type Out = TextFlow } = ???
implicit val `case3`: JudgeFlow[???] { type Out = RDDFlow } = ???
}
def judgeFlow[In](in: In)(implicit jf: JudgeFlow[In]): jf.Out = jf.judgeFlow(in)
但问题是类型是在编译时解析的。您似乎想根据字符串的值选择一个案例,即在运行时。所以在编译时你不能 return 比 Flow
更具体的类型。
很难完全猜出您的用例。
但是使用Scala reflection你可以试试
import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror
def judgeFlow(path:String): Type = {
Flow.getStoreType(path) match {
case StoreType.tdw =>
typeOf[DataFrameFlow]
case StoreType.hdfs =>
typeOf[TextFlow]
}
}
def createFlow(typeInfo: Type): Flow = {
val constructorSymbol = typeInfo.decl(termNames.CONSTRUCTOR).asMethod
val classSymbol = typeInfo.typeSymbol.asClass
val classMirror = currentMirror.reflectClass(classSymbol)
val constructorMirror = classMirror.reflectConstructor(constructorSymbol)
constructorMirror().asInstanceOf[Flow]
}
我有很多class,例如DataFrameFlow
、TextFlow
、RDDFlow
。它们都派生自基数 class Flow
.
现在我想编写一个函数 judgeFlow
,它可以从 path: String
和 return 代表确切 Flow
类型的东西中读取,我可以从中创建相应的实例。整个代码如下
def judgeFlow(path:String) = /*1*/ {
Flow.getStoreType(path) match {
case StoreType.tdw =>
DataFrameFlow
case StoreType.hdfs =>
TextFlow
}
}
def createFlow(typeInfo:/*2*/) = /*3*/{
new typeInfo()
}
可是,1、2、3处我不知道怎么写
编辑
知道如何构建它们还不够,因为我还想要以下内容:
- 通过
typeInfo
进行模式匹配
- 一些方法
asInstanceOf
编辑 2
Flow
abstract class Flow(var outputName: String) extends Serializable{
def this() = this("")
...
}
DataFrameFlow
class DataFrameFlow(d: DataFrame, path: String) extends Flow {
var data: DataFrame = d
def this(data: DataFrame) = this(data, "")
def this(path: String) = this(null, path)
def this() = this(null, "")
...
}
模式匹配不能return 来自不同案例的不同类型。通过模式匹配 returned 的类型是 cases returned 类型的最小上限。
当有人想要 return 不同类型时,很可能 he/she 想要 class.
类型sealed abstract class Flow
class DataFrameFlow extends Flow
class TextFlow extends Flow
class RDDFlow extends Flow
trait JudgeFlow[In] {
type Out <: Flow
def judgeFlow(in: In): Out
}
object JudgeFlow {
implicit val `case1`: JudgeFlow[???] { type Out = DataFrameFlow } = ???
implicit val `case2`: JudgeFlow[???] { type Out = TextFlow } = ???
implicit val `case3`: JudgeFlow[???] { type Out = RDDFlow } = ???
}
def judgeFlow[In](in: In)(implicit jf: JudgeFlow[In]): jf.Out = jf.judgeFlow(in)
但问题是类型是在编译时解析的。您似乎想根据字符串的值选择一个案例,即在运行时。所以在编译时你不能 return 比 Flow
更具体的类型。
很难完全猜出您的用例。
但是使用Scala reflection你可以试试
import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror
def judgeFlow(path:String): Type = {
Flow.getStoreType(path) match {
case StoreType.tdw =>
typeOf[DataFrameFlow]
case StoreType.hdfs =>
typeOf[TextFlow]
}
}
def createFlow(typeInfo: Type): Flow = {
val constructorSymbol = typeInfo.decl(termNames.CONSTRUCTOR).asMethod
val classSymbol = typeInfo.typeSymbol.asClass
val classMirror = currentMirror.reflectClass(classSymbol)
val constructorMirror = classMirror.reflectConstructor(constructorSymbol)
constructorMirror().asInstanceOf[Flow]
}