我不了解 Lift,因此无法回答任何与 Lift 相关的问题。但是,我确实想出了一种方法来解决您的一个问题,即如何编写一系列检查然后操作的操作,而不求助于嵌套模式匹配。
这里使用的主要数据类型是 Option,但我相信它会很容易适应您的需求。我们在这里要完成的是做一个序列
- 检查条件
- 成功则继续
- 终止并以其他方式返回某些东西
代码一旦遇到 None 就会发生一种短路,因此当动作序列返回时返回值被保留。要使用,以 Option 开头,如果 Option 是 Some,则写“ifSome”,如果 Option 是 None,则写“ifNone”,继续直到序列完成。如果在序列中的任何点遇到 None,则保留从“isNone”的按名称调用参数返回的选项,并在调用最终的“toOption”时返回。使用“toOption”取回实际的 Option 结果。
查看“main”中的示例以了解某些用例。祝你好运!
object Options {
class RichOption[A](a: Option[A]) {
def ifSome[B](f: A => Option[B]): RichOption[B] = a match {
case Some(x) => new RichOption(f(x))
case None => this.asInstanceOf[RichOption[B]]
}
def ifNone[B](f: => Option[B]): RichOption[B] = a match {
case Some(_) => this.asInstanceOf[RichOption[B]]
case None => new RichNone(f)
}
def toOption[A] = a
}
class RichNone[A](a: Option[A]) extends RichOption[A](a) {
override def ifSome[B](f: A => Option[B]): RichOption[B] = this.asInstanceOf[RichOption[B]]
override def ifNone[B](f: => Option[B]): RichOption[B] = this.asInstanceOf[RichOption[B]]
}
implicit def option2RichOption[A](a: Option[A]): RichOption[A] = new RichOption(a)
def main(args: Array[String]) {
println(Some("hello") ifSome(s => Some(s.toUpperCase)) toOption) // prints Some(HELLO)
println(Some("hello") ifNone(Some("empty")) toOption) // prints Some(hello)
println(Some("hello") ifSome(s => Some(s.toUpperCase)) ifNone(Some("empty")) toOption) // prints Some(HELLO)
println(Some("hello") ifNone(Some("empty")) ifSome(s => Some(s.toUpperCase)) toOption) // prints Some(HELLO)
println((None: Option[String]) ifSome(s => Some(s.toUpperCase)) toOption) // prints None
println((None: Option[String]) ifNone(Some("empty")) toOption) // prints Some(empty)
println((None: Option[String]) ifSome(s => Some(s.toUpperCase)) ifNone(Some("empty")) toOption) // prints Some(empty)
println((None: Option[String]) ifNone(Some("empty")) ifSome(s => Some(s.toUpperCase)) toOption) // prints Some(empty)
println(Some("hello world") ifSome(s => Some(s.toUpperCase)) ifNone(Some("empty")) ifSome(s => Some(s.length)) ifNone(None) toOption) // prints Some(11)
println(Some("hello world") ifSome(_ => None) ifNone(Some("goodbye world")) ifSome(s => Some(s.length)) ifNone(None) toOption) // prints Some(goodbye world)
println((None: Option[String]) ifSome(s => Some(s.toUpperCase)) ifNone(Some("empty")) ifSome(s => Some(s.length)) ifNone(None) toOption) // prints Some(empty)
println((None: Option[String]) ifSome(_ => None) ifNone(Some("goodbye world")) ifSome(s => Some(s.length)) ifNone(None) toOption) // prints Some(goodbye world)
}
}