在 scala 中有什么方法可以 return 一个类型吗?

Is there some way in scala that I can return a type?

我有很多class,例如DataFrameFlowTextFlowRDDFlow。它们都派生自基数 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处我不知道怎么写

编辑

知道如何构建它们还不够,因为我还想要以下内容:

  1. 通过typeInfo
  2. 进行模式匹配
  3. 一些方法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]
}