【问题标题】:nested "if"/"match" statement in scala: better approach?scala中嵌套的“if”/“match”语句:更好的方法?
【发布时间】:2012-12-27 17:49:28
【问题描述】:

我有一系列验证函数,如果有,则返回 Option[Problem],如果没有发现验证问题,则返回 None。 我想写一个简单的函数,调用每个验证函数,停止并返回第一个非无结果。

我当然可以用“java-style”编写这个方法,但我想知道是否存在更好的方法。

编辑

这是最初的 Java 解决方案:

validate01(arg);
validate02(arg);
validate03(arg);
...

如果出现问题,每个方法都会抛出异常。在编写 Scala 时,我会远离异常。

【问题讨论】:

  • “更好”是什么意思?什么是“java 风格”?
  • 你能提供你想改进的代码示例吗?
  • 来人,给 Scala 添加 monad!
  • @RobertHarvey "java-style" 表示详细方法 "if/else if/else if..."(或类似的使用匹配)

标签: scala if-statement


【解决方案1】:

例如,假设我们要验证String。我们的验证函数接受一个String 和一个验证器列表,它们是从StringOption[Problem] 的函数。我们可以这样实现它:

def firstProblem(validators: List[String => Option[Problem]], s:String) =
  validators.view.flatMap(_(s)).headOption

这将通过将每个验证函数应用于字符串并仅在结果为Some 时保留结果来创建一个新列表。然后我们取这个 List 的第一个元素。由于调用了view,列表将仅根据需要进行计算。因此,一旦发现第一个问题,就不会调用其他验证器。

【讨论】:

  • 你也可以这样写 - def firstProblem(validators: List[String => Option[Problem]], s: String) = { var r: Option[Problem] = None; for(v
  • @SpiderPig:你可以,但他要求的是功能性解决方案。
  • @KimStebel 是的,你是对的,我要求的是功能性解决方案
【解决方案2】:

如果您在编译时有有限且已知的验证次数,您可以在选项上使用 .orElse:

def foo(x: Int): Option[Problem] = ...
def bar(x: Int): Option[Problem] = ...
...
def baz(x: Int): Option[Problem] = ...


foo(1) orElse bar(2) orElse .. baz(n)

【讨论】:

  • 您还可以使用 foldLeft 将 orElse 应用于任意 Seq of Validations;类似vs.foldLeft(Option.empty[Problem]) { (result, validation) => result orElse validation(n) }
  • @GregCampbell:然后你就有了我的解决方案,只是更复杂而不是懒惰。
【解决方案3】:

也许你想要——假设验证函数不带参数

def firstProblem(fs: (() => Option[Problem])*) = {
  fs.iterator.map(f => f()).find(_.isDefined).flatten
}

您将获得一个现有的Option[Problem](如果有),或者None(如果它们都成功)。如果您需要将参数传递给函数,那么您需要解释这些参数是什么。例如,你可以

def firstProblem[A](a: A)(fs: (A => Option[Problem])*) = /* TODO */

如果您可以将相同的参数传递给所有它们。你可以这样使用它:

firstProblem(myData)(
  validatorA,
  validatorB,
  validatorC,
  validatorD
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 1970-01-01
    相关资源
    最近更新 更多