我有一系列验证函数,如果没有发现验证问题,则返回 Option[Problem](如果有)或 None。我想编写一个简单的函数来调用每个验证函数,停止并返回第一个非无结果。
当然,我可以用“java-style”编写这个方法,但我想知道是否存在更好的方法。
编辑
这是最初的 Java 解决方案:
validate01(arg);
validate02(arg);
validate03(arg);
...
如果出现问题,每个方法都会引发异常。在编写 Scala 时,我会远离异常。
我有一系列验证函数,如果没有发现验证问题,则返回 Option[Problem](如果有)或 None。我想编写一个简单的函数来调用每个验证函数,停止并返回第一个非无结果。
当然,我可以用“java-style”编写这个方法,但我想知道是否存在更好的方法。
编辑
这是最初的 Java 解决方案:
validate01(arg);
validate02(arg);
validate03(arg);
...
如果出现问题,每个方法都会引发异常。在编写 Scala 时,我会远离异常。
例如,假设我们要验证一个String
. 我们的验证函数接受一个String
和一个验证器列表,它们是从String
到的函数Option[Problem]
。我们可以以这样的功能方式实现它:
def firstProblem(validators: List[String => Option[Problem]], s:String) =
validators.view.flatMap(_(s)).headOption
这通过将每个验证函数应用于字符串并仅在结果为 时才保留结果来创建一个新列表Some
。然后我们取这个 List 的第一个元素。由于调用view
,列表将仅根据需要计算。因此,一旦发现第一个问题,就不会调用其他验证器。
如果您在编译时有有限且已知的验证次数,则可以在选项上使用 .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)
也许你想要——假设验证函数不带参数
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
)