我有这种结构:
if(condition1)
lengthyOperation1
else if(condition2)
lengthyOperation2
else if(condition3)
lengthyOperation3
...
else
lastLengthyOperation
我想以下列方式表达:
lazy val seq = Seq(
condition1 -> lengthyOperation1,
condition2 -> lengthyOperation2,
condition3 -> lengthyOperation3,
...
true -> lastLengthyOperation
)
seq.find(_._1).match { case(_, v) => v }
问题是最后一行的评估在到达“seq”时执行所有冗长的操作。我该怎么做才能让长时间的操作只在需要时执行?
注意:条件不可能是同一表达式的模式匹配(即我不能使用单个匹配语句)
编辑:我应该使用Stream吗?
答案 0 :(得分:0)
我猜您的意思是Seq
,而不是Map
。
您可以在此使用Seq
代替if
序列,但我认为它不具备可读性。
您应该在getOrElse
之后使用find
。假设每个lengthyOperationN
都是一个函数:
seq.find(_._1).map{_._2}.getOrElse(lastLengthyOperation).apply()
答案 1 :(得分:0)
你的方法的问题是你在错误的地方懒惰。当你宣布
时lazy val seq = Seq(
condition1 -> lengthyOperation1,
...
)
然后一旦你触摸seq
,整个序列都会进行所有冗长的操作,无论你触摸哪一个。序列的元素是严格的。
您可以使用Stream
执行您想要的操作,但我想使用专为此目的设计的Option
更容易。让我们在选项上声明一个帮助器隐式函数。如果在Some
上调用它,则它不会执行任何操作。如果在None
上调用它,它会检查一个条件,如果它满足,则返回Some(result)
:
implicit class IfOption[A](opt: Option[A]) {
def ?>[B >: A](condition: Boolean, result: => B): Option[B] =
opt.orElse(if (condition) Some(result) else None);
}
现在我们可以做像
这样的事情println(
None
?> (1 != 1, "A")
?> (2 == 2, "B")
?> (3 == 2, "C")
)
其中打印表达式的类型为Option[String]
并打印Some(B)
或
println(
None
?> (1 != 1, "Yes")
?> (2 != 2, "No")
?> (3 != 2, "heck")
getOrElse ("ah")
)
其中类型只是“String”。