【问题标题】:Scala: Return multiple data types from functionScala:从函数返回多种数据类型
【发布时间】:2015-07-09 13:16:23
【问题描述】:

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

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

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

【问题讨论】:

标签: scala


【解决方案1】:

您可以使用 Scala 库提供的 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]]

【讨论】:

  • 如果我为多种类型嵌套它们,我如何引用嵌套结构?通过相应地嵌套左/右,如 Right(Left(42))?
【解决方案2】:

正如在 cmets 中已经指出的,你最好使用 Either 来完成这个任务,但如果你真的想要它,你可以使用implicits

  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")

【讨论】:

    【解决方案3】:

    我会让用户输入的内容不那么隐晦,更明确。以下是三个例子:

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

    这很好也很简单。或者,我们可以有一个使用隐式上下文返回适当柯里化函数的函数:

    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")
    

    【讨论】:

    • 这个很棒而优雅的答案怎么不被赞成?!
    猜你喜欢
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 1970-01-01
    • 2014-05-29
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多