如何根据Scala中的某些条件计算值

如何根据Scala中的某些条件计算值,scala,if-statement,immutability,tail-recursion,Scala,If Statement,Immutability,Tail Recursion,我实现了一个递归方法来检查字符串中的括号数是否有效。这是密码 def balance(chars: List[Char]): Boolean = { @tailrec def isValid(newChars: List[Char], difference: Int): Boolean = { if (newChars.isEmpty) difference == 0 else if (difference < 0) false else

我实现了一个递归方法来检查字符串中的括号数是否有效。这是密码

def balance(chars: List[Char]): Boolean = {
    @tailrec
    def isValid(newChars: List[Char], difference: Int): Boolean = {
      if (newChars.isEmpty) difference == 0
      else if (difference < 0) false
      else {
        var newDifference = difference // Scala IDE gives warning here

        if (newChars.head == '(') newDifference = difference + 1
        else if (newChars.head == ')') newDifference = difference - 1

        isValid(newChars.tail, newDifference)
      }
    }

    isValid(chars, 0)
}
正如代码中提到的,Scala IDE在这一行中抱怨说

避免可变的局部变量

我真的不知道如何在不使用if/else的情况下计算
newDifference
的值。我可以看到的另一个选项是直接调用if/else梯形图中的
isValid
方法,计算值为newDifference

我仍在学习Scala,因此我想知道在不改变局部变量(或任何其他警告)的情况下编写此代码的最佳方法是什么。

您可以编写:

val newDifference =
  if (newChars.head == '(') difference + 1
  else if (newChars.head == ')') difference - 1
  else difference;
如果Scala中的是一个表达式,则使用
匹配
,在本例中,这将被视为更惯用:

val newDifference = newChars.head match {
  case '(' => difference + 1
  case ')' => difference - 1
  case _   => difference
}
整个函数可以在
newChars
上转换为单个
match
,但我将把它留给您。有关一些想法,请参见第一个示例。

您可以编写:

val newDifference =
  if (newChars.head == '(') difference + 1
  else if (newChars.head == ')') difference - 1
  else difference;
如果Scala中的是一个表达式,则使用
匹配
,在本例中,这将被视为更惯用:

val newDifference = newChars.head match {
  case '(' => difference + 1
  case ')' => difference - 1
  case _   => difference
}

整个函数可以在
newChars
上转换为单个
match
,但我将把它留给您。有关一些想法,请参见第一个示例。

人们使用模式匹配。这样可以避免可变变量和“if/else梯形图”,这会产生可怕的“意大利面代码”

def有效(chars:List[Char],ps:Int=0)=(chars,ps)匹配{
案例(Nil,)=>ps==0
如果ps<0=>false,则为case(u,u)
大小写('('::tail,ps)=>isValid(tail,ps+1)
大小写(')::tail,ps)=>isValid(tail,ps-1)
大小写(u216;::tail,ps)=>isValid(tail,ps)
}

人们使用模式匹配来实现这一点。这样可以避免可变变量和“if/else梯形图”,这会产生可怕的“意大利面代码”

def有效(chars:List[Char],ps:Int=0)=(chars,ps)匹配{
案例(Nil,)=>ps==0
如果ps<0=>false,则为case(u,u)
大小写('('::tail,ps)=>isValid(tail,ps+1)
大小写(')::tail,ps)=>isValid(tail,ps-1)
大小写(u216;::tail,ps)=>isValid(tail,ps)
}

+1您的第二个示例,匹配模式看起来非常好,这就是我要找的。感谢@Dogbert+1您的第二个示例,匹配模式看起来非常好,这就是我要找的。谢谢@DogbertGreat!!对我最初的代码有多大的修改啊。您的答案是一个很好的例子,说明了匹配模式如何生成意大利面代码。谢谢你这么说。太好了!!对我最初的代码有多大的修改啊。您的答案是一个很好的例子,说明了匹配模式如何生成意大利面代码。谢谢你这么说。