在短路操作中将空 list/Seq 视为失败的惯用(快速)方法是什么?
What is the idiomatic (and fast) way of treating the empty list/Seq as failure in a short-circuiting operation?
我有一种情况,我正在使用函数对规则应用程序进行建模,每个函数返回应用时将采取的操作,或者,如果无法应用规则,则返回空列表。我有许多规则,我想按顺序和短路尝试。在我习惯的其他语言中,我会将空序列视为 false/None 并将它们与 orElse
链接起来,如下所示:
def ruleOne(): Seq[Action] = ???
def ruleTwo(): Seq[Action] = ???
def ruleThree(): Seq[Action] = ???
def applyRules(): Seq[Action] = ruleOne().orElse(ruleTwo).orElse(ruleThree)
但是,据我了解情况,。
我可以使用 return
,这让我感觉很糟糕,或者更糟糕的是,嵌套的 if
语句。 if let
在这里会很棒,但 AFAICT Scala 没有。
这里的惯用方法是什么?
这里有不同的方法。
其中之一是将所有操作组合在一个 Seq 中(因此创建一个 Seq[Seq[Action]]
),然后使用 find
(它将 return 匹配给定条件的第一个元素)。所以,例如:
Seq(ruleOne, ruleTwo, ruleThree).find(_.nonEmpty).getOrElse(Seq.empty[Action])
我不清楚你的域应用,但最后的getOrElse
允许将find
方法产生的Option
转换为Seq
。这种方法虽然评估了所有序列(没有短路)。
另一种方法是用一种方法来丰富 Seq
,该方法模拟了您对 orElse
的想法,使用皮条客我的 library/extensions 方法:
implicit class RichSeq[T](left: Seq[T]) {
def or(right: => Seq[T]): Seq[T] = if(left.isEmpty) { right } else { left }
}
名称参数启用短路评估。实际上,仅当 左侧序列为空时 才计算右侧序列。
Scala 3 对这种抽象有更好的语法:
extension[T](left: Seq[T]){
def or(rigth: => Seq[T]): Seq[T] = if(left.nonEmpty) { left } else { rigth }
}
这样可以调用:
ruleOne or ruleTwo or ruleThree
我有一种情况,我正在使用函数对规则应用程序进行建模,每个函数返回应用时将采取的操作,或者,如果无法应用规则,则返回空列表。我有许多规则,我想按顺序和短路尝试。在我习惯的其他语言中,我会将空序列视为 false/None 并将它们与 orElse
链接起来,如下所示:
def ruleOne(): Seq[Action] = ???
def ruleTwo(): Seq[Action] = ???
def ruleThree(): Seq[Action] = ???
def applyRules(): Seq[Action] = ruleOne().orElse(ruleTwo).orElse(ruleThree)
但是,据我了解情况,
我可以使用 return
,这让我感觉很糟糕,或者更糟糕的是,嵌套的 if
语句。 if let
在这里会很棒,但 AFAICT Scala 没有。
这里的惯用方法是什么?
这里有不同的方法。
其中之一是将所有操作组合在一个 Seq 中(因此创建一个 Seq[Seq[Action]]
),然后使用 find
(它将 return 匹配给定条件的第一个元素)。所以,例如:
Seq(ruleOne, ruleTwo, ruleThree).find(_.nonEmpty).getOrElse(Seq.empty[Action])
我不清楚你的域应用,但最后的getOrElse
允许将find
方法产生的Option
转换为Seq
。这种方法虽然评估了所有序列(没有短路)。
另一种方法是用一种方法来丰富 Seq
,该方法模拟了您对 orElse
的想法,使用皮条客我的 library/extensions 方法:
implicit class RichSeq[T](left: Seq[T]) {
def or(right: => Seq[T]): Seq[T] = if(left.isEmpty) { right } else { left }
}
名称参数启用短路评估。实际上,仅当 左侧序列为空时 才计算右侧序列。
Scala 3 对这种抽象有更好的语法:
extension[T](left: Seq[T]){
def or(rigth: => Seq[T]): Seq[T] = if(left.nonEmpty) { left } else { rigth }
}
这样可以调用:
ruleOne or ruleTwo or ruleThree