我试图找出为什么我的curried功能以下列方式运行。我构建了函数确保采用更多函数方法而不是多个if-then语句来完成同样的事情。
我发现今天有一个bug会运行一些测试,如果第一个中的条件确保功能,例如确保(contents.hasNext&& acc!= null)为true,错误条件或第二个争论仍然会被评估并成为重写函数。
我可以解决这个问题,如果我简单地改变这个:确保(contents.hasNext)到这个:确保(contents.hasNext&& acc == null)但我正在努力为什么会发生这种情况。
是否有更明显(或更好)的解决方案?
def ensure[T](f: => Boolean)(truth: => T, lie: T) = if (f) truth else lie
def lines(): Stream[String] = {
def matchLine(text: String, acc: String): Stream[String] = text match {
...
case NewLine(string) =>
ensure(contents.hasNext && acc != null)(acc +: matchLine(contents.next, string),
ensure(contents.hasNext)(matchLine(contents.next, string), acc +: string +: empty))
...
}
ensure(contents.hasNext)(matchLine(contents.next, null), empty)
}
答案 0 :(得分:3)
(truth: => T, lie: T)
这意味着,每次truth
在您的函数中使用时(仅当时),将评估为truth
参数指定的表达式,而lie
将完全执行一旦你的函数开始执行之前。换句话说:truth
按名称传递,lie
则不传递。为了实现你想要的行为,你需要通过名称传递两个(另一方面,通过名称传递条件并不是必需的,因为在所有情况下它将在函数的开头只被评估一次):
ensure[T](f: Boolean)(truth: => T, lie: => T) = if (f) truth else lie
那就是说,我不同意用一个基本上是if-then-else包装的函数替换if-then-else表达式,使你的代码更具功能性。