Scala以什么顺序/如何评估函数定义中的条件?

时间:2013-09-26 22:12:07

标签: scala if-statement conditional-statements

在尝试编写一个简单的括号平衡函数时,我了解到我不知道scala如何评估if语句。

def balance(chars: List[Char]): Boolean = {
  def loop(chars: List[Char], opened: Int): Boolean = {
    println(opened)
    println(chars.head)
    if (opened < 0) return false
    if (chars.isEmpty && opened == 0) return true
    if (chars.isEmpty && opened > 0) return false
    if (!chars.isEmpty && chars.head.toString == "(") loop(chars.tail, opened+1)
    if (!chars.isEmpty && chars.head.toString == ")") loop(chars.tail, opened-1)
    else loop(chars.tail, opened)
  }
loop(chars, 0)
}

当我运行它时,通过第三次迭代,它将println(打开)并声明打开= -1。我想象(打开&lt; 0)----&gt; (-1&lt; 0)-----&gt;是的,所以我会回复假。事实并非如此 - 为什么?

1 个答案:

答案 0 :(得分:2)

Scala按照声明的顺序评估if个表达式。这个算法的问题在于它假设只有在没有其他else条件为真的情况下才会评估最后的if表达式,但是如果输入'(X)'',则会创建两个递归树:一个用于条件!chars.isEmpty && chars.head.toString == "(",另一个用于else loop(chars.tail, opened)。这会产生一种印象,即当打开= -1时递归没有结束,但事实上你所看到的是'else'递归树。

解决方案?您只是错过了else

if (!chars.isEmpty && chars.head.toString == "(") loop(chars.tail, opened+1) **else**

(注意:可以使用match...case语句改进此代码。这将阻止先前的else问题发生。 此外,您可以将字符与字符进行比较。无需将其转换为字符串:chars.head.toString == "(" =&gt; chars.head == '('

*编辑* 在您发表评论之后,您可以在列表结构中使用模式匹配:

def loop(chars: List[Char], opened: Int): Boolean = {
    if (opened < 0) return false else 
    chars match {
    case Nil => opened == 0
    case '('::tail => loop(tail, opened + 1)
    case ')'::tail => loop(tail, opened -1)
    case x::tail => loop(tail, opened)
}

我希望这会有所帮助。