Scala中if语句未正确返回致代码执行异常问题排查
Scala countChange函数执行异常原因分析
你的代码
def countChange(money: Int, coins: List[Int]): Int = { println(s"countChange(${money}, ${coins}) - ${coins.isEmpty}") if money < 0 || coins.isEmpty then 0 if money == 0 then 1 else println(s"${coins.head}") -1 }
调用方式
assertEquals(countChange(1, List()), 0)
错误输出
countChange(1, List()) - true java.util.NoSuchElementException: head of empty list at scala.collection.immutable.Nil$.head(List.scala:662) at scala.collection.immutable.Nil$.head(List.scala:661) at recfun.RecFun$.countChange(RecFun.scala:45) at recfun.RecFunSuite.$init$$$anonfun$5(RecFunSuite.scala:27)
问题原因
你写的是两个独立的if表达式,而非链式的if-else结构。Scala中,独立的if会依次执行:
- 第一个
if判断money <0 || coins.isEmpty为true,返回0,但函数不会立刻终止,会继续执行后面的代码。 - 接着执行第二个
if money ==0,此时money是1,条件不成立,进入else块。 else块里调用coins.head,但coins是空列表,直接抛出NoSuchElementException。
简单说,你以为第一个if返回后函数就结束了,但实际上Scala会把所有代码都跑完,除非用return(不推荐)或者用else if串联条件。
修复方案
把条件改成链式的if-else,这样满足某个条件后就直接返回,跳过后续分支:
def countChange(money: Int, coins: List[Int]): Int = { println(s"countChange(${money}, ${coins}) - ${coins.isEmpty}") if money < 0 || coins.isEmpty then 0 else if money == 0 then 1 else println(s"${coins.head}") -1 }
或者用模式匹配(更符合Scala风格):
def countChange(money: Int, coins: List[Int]): Int = { println(s"countChange(${money}, ${coins}) - ${coins.isEmpty}") (money, coins) match { case (_, Nil) => 0 case (m, _) if m < 0 => 0 case (0, _) => 1 case (m, cs) => println(s"${cs.head}") -1 } }
内容的提问来源于stack exchange,提问作者Chota Bheem
相关产品推荐
相关产品推荐

