Scala function return behaviour

use*_*513 0 recursion scala

I'm trying to solve this epfl scala course homework where they ask me to write the sum of a list. I can do it if I use return statements or if use match statement but I can't understand why it wouldn't work using if/else without return statement.

def sum(xs: List[Int]): Int = xs {
  if (xs.isEmpty) {
    0
  } else {
    xs.head + sum(xs.tail)
  }
}
Run Code Online (Sandbox Code Playgroud)

The run time error that I get when I run sum(List(1,3,2)) is

java.lang.IndexOutOfBoundsException: 0
  at scala.collection.LinearSeqOptimized.apply(LinearSeqOptimized.scala:67)
  at scala.collection.LinearSeqOptimized.apply$(LinearSeqOptimized.scala:65)
  at scala.collection.immutable.List.apply(List.scala:89)
  at example.Lists$.sum(Lists.scala:39)
  at example.Lists$.sum(Lists.scala:39)
  at example.Lists$.sum(Lists.scala:39)
  at example.Lists$.sum(Lists.scala:39)
Run Code Online (Sandbox Code Playgroud)

If I replace 0 in the code with 100 the error message changes to java.lang.IndexOutOfBoundsException: 100 . It's like it is trying to access the N'th element of the list and all I need is a return. If I add the two return statements all works as expected.

Can you please shed some light ?

jro*_*ook 6

The root cause is in the first line of the function declaration:

def sum(xs: List[Int]): Int = xs {
Run Code Online (Sandbox Code Playgroud)

This is equivalent with:

def sum(xs: List[Int]): Int = xs.apply(<Some function>) 
Run Code Online (Sandbox Code Playgroud)

For example xs.apply(3) means get item with index 3 from the list xs.

Scala将评估方括号内的代码,并尝试将结果应用于xs。当它展开递归时,它将最终进入一个空列表,但是程序要求它返回xs(0)不存在的IndexOutOfBoundsException错误,因此将返回错误。

要使该程序执行您想要的操作,只需xs从函数体开头删除即可:

def sum(xs: List[Int]): Int = {
Run Code Online (Sandbox Code Playgroud)

现在:

sum(List(1,3,2))
res0: Int = 6
Run Code Online (Sandbox Code Playgroud)

  • 同样,如果方法的整个主体是单个表达式,则无需创建语句块。只是失去大括号。条件表达式也是如此:def sum(xs:List [Int]):Int = if(xs.isEmpty)0 else xs.head + sum(xs.tail)` (2认同)