在 Scala 中有什么方法可以返回一个类型吗? [英] Is there some way in scala that I can return a type?

查看:51
本文介绍了在 Scala 中有什么方法可以返回一个类型吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有很多类,例如DataFrameFlowTextFlowRDDFlow.它们都派生自基类 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:

  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, "")
...
}

推荐答案

模式匹配不能从不同的情况返回不同的类型.模式匹配返回的类型是 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆