Scala Cats Effect中遇首个true时终止List[IO[Boolean]]遍历的方法
使用Scala Cats Effect实现规则验证的短路逻辑
你需要按顺序执行规则验证,一旦遇到首个返回true的规则就立即终止遍历,所有规则都不通过时抛出异常。Cats Effect提供了现成的Monadic集合操作符来实现这种短路逻辑,无需手动编写循环控制。
方案1:使用findM(保留首个通过的规则实例)
findM是Monadic版本的find,它会按顺序遍历集合,对每个元素执行IO操作,一旦找到返回true的结果就立刻停止后续遍历,返回包含该元素的IO[Option[Rule]]。
import cats.effect.IO import cats.syntax.all._ case class Rule1() { def validate(): IO[Boolean] = IO.pure(false) } case class Rule2() { def validate(): IO[Boolean] = IO.pure(false) } case class Rule3() { def validate(): IO[Boolean] = IO.pure(true) } val rules = List(Rule1(), Rule2(), Rule3()) val validation: IO[Unit] = rules.findM(_.validate()) .flatMap { case Some(passedRule) => // 若需要记录通过的规则,可在此处理(比如打印日志) IO.unit case None => IO.raiseError(new RuntimeException("所有规则验证均未通过")) }
方案2:使用existsM(仅判断是否存在通过的规则)
如果不需要保留通过的规则实例,只需要确认是否有规则通过,existsM更简洁——它同样是短路执行,找到首个true就停止,直接返回IO[Boolean]表示是否存在符合条件的元素。
val validation: IO[Unit] = rules.existsM(_.validate()) .flatMap { hasPassed => if (hasPassed) IO.unit else IO.raiseError(new RuntimeException("所有规则验证均未通过")) }
关键说明
这两个操作符都是短路执行的:以你的示例为例,Rule1和Rule2验证返回false后,会执行Rule3的validate方法,一旦得到true就立刻终止,不会再执行后续规则(如果有的话),完全符合你“遇到首个true就退出”的需求,避免了不必要的IO操作。
内容的提问来源于stack exchange,提问作者Shivam
相关产品推荐
相关产品推荐

