在 Scala 中有什么方法可以返回一个类型吗? [英] Is there some way in scala that I can return a type?
问题描述
我有很多类,例如DataFrameFlow
、TextFlow
、RDDFlow
.它们都派生自基类 Flow
.
I have a lot of classes such as DataFrameFlow
, TextFlow
, RDDFlow
. They all derive from base class Flow
.
现在我想编写一个函数 judgeFlow
,它可以从 path: String
中读取并返回一些代表确切的 Flow
类型的东西,我从中可以创建相应的实例.整个代码如下
Now I want to write a function judgeFlow
which can read from a path: String
and return something representing exact Flow
type from which I can create corresponding instance. The whole code seems like the following
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 中写.
However, I don't know how to write in place 1, 2 and 3.
编辑
知道如何构建它们在这里是不够的,因为我还想要以下内容:
Knowing how to construct them is not enough here, because I also want the following:
- 通过
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, "")
...
}
推荐答案
模式匹配不能从不同的情况返回不同的类型.模式匹配返回的类型是 case 返回类型的最小上限.
Pattern matching can't return different types from different cases. The type returned by pattern matching is the least upper bound of types returned in cases.
当有人想要返回不同的类型时,他/她很可能想要一个类型类.
When someone wants to return different types, most probably he/she wants a type 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)
但问题是类型是在编译时解析的.您似乎想根据字符串的值(即在运行时)选择一个案例.所以你不能在编译时返回比 Flow
更具体的类型.
But the trouble is that types are resolved at compile time. You seem to want to choose a case based on a value of string i.e. at runtime. So you can't return more specific types than just Flow
at compile time.
flatMap 与 Shapeless yield FlatMapper not found
很难完全猜测您的用例.
It's hard to guess your use case completely.
但是使用 Scala 反射你可以试试
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]
}
这篇关于在 Scala 中有什么方法可以返回一个类型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!