Scala:从函数返回多种数据类型

时间:2015-07-09 13:16:23

标签: scala

这有点是一个理论问题,但我可能想做些什么。是否可以从Scala函数返回多个数据数据类型但限制允许的类型?我知道我可以通过指定它来返回一种类型,或者我基本上可以通过不指定返回类型来允许任何数据类型,但我想返回3种特定数据类型中的一种以保留一点类型安全性。有没有办法在返回类型中写'或',如:

def myFunc(input:String): [Int || String] = { ...}

主要的上下文是尝试编写通用数据加载脚本。我的一些用户使用Spark,一些Scalding,谁知道接下来会发生什么。我希望我的用户能够使用可能返回RichPipe,RDD或其他一些数据格式的通用加载脚本,具体取决于他们使用的框架,但我不想完全抛弃类型安全性。< / p>

3 个答案:

答案 0 :(得分:8)

您可以使用Scala Library提供的Either类型。

def myFunc(input:String): Either[Int, String] = {
    if (...) 
        Left(42) // return an Int
    else
        Right("Hello, world") // return a String
}

您可以通过嵌套使用两种以上的类型,例如Either[A,Either[B,C]]

答案 1 :(得分:1)

正如评论中已经提到的,你最好使用Either来完成这项任务,但是如果你真的想要它,你可以使用暗示

  object IntOrString {
    implicit def fromInt(i: Int): IntOrString = new IntOrString(None, Some(i))
    implicit def fromString(s: String): IntOrString = new IntOrString(Some(s), None)
  }
  case class IntOrString(str: Option[String], int: Option[Int])
  implicit def IntOrStringToInt(v: IntOrString): Int = v.int.get
  implicit def IntOrStringToStr(v: IntOrString): String = v.str.get

  def myFunc(input:String): IntOrString = {
    if(input.isEmpty) {
      1
    }  else {
      "test"
    }
  }

  val i: Int = myFunc("")
  val s: String = myFunc("123")
  //exception
  val ex: Int = myFunc("123")

答案 2 :(得分:0)

我使用户的输入更少隐式和更明确。以下是三个例子:

def loadInt(input: String): Int = { ... }

def loadString(input: String): String = { ... }

那很好又简单。或者,我们可以使用一个函数,使用隐式上下文返回适当的curried函数:

def loader[T]()(implicit context: String): String => T = {
  context match {
    case "RDD" => loadInt _ // or loadString _
  }
}

然后用户会:

implicit val context: String = "RDD" // simple example
val loader: String => Int = loader()
loader(input)

或者,可以将其转换为显式参数:

val loader: String => Int = loader("RDD")