Scala функция, возвращающая поведение - PullRequest
0 голосов
/ 04 октября 2019

Я пытаюсь решить эту домашнюю работу по курсу epfl scala, где меня просят написать сумму в списке. Я могу сделать это, если я использую операторы return или операторы match, но я не могу понять, почему это не сработает, используя if / else без оператора return.

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

Ошибка времени выполнения, которую я получаюкогда я запускаю сумму (Список (1,3,2)) равен

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)

Если я заменю 0 в коде на 100, сообщение об ошибке изменится на java.lang.IndexOutOfBoundsException: 100. Как будто он пытается получить доступ к N-му элементу списка, и все, что мне нужно, это возврат. Если я добавлю два оператора return, все будет работать как положено.

Не могли бы вы пролить свет?

1 Ответ

6 голосов
/ 04 октября 2019

Основная причина находится в первой строке объявления функции:

def sum(xs: List[Int]): Int = xs {

Это эквивалентно:

def sum(xs: List[Int]): Int = xs.apply(<Some function>) 

Например, xs.apply(3) означает получить элемент с индексом 3из списка xs.

Scala оценит код в скобках и попытается применить результат к xs. Поскольку он раскручивает рекурсию, он в конечном итоге попадет в пустой список, но программа просит вернуть xs(0), который не существует, таким образом, ошибка IndexOutOfBoundsException.

Чтобы заставить эту программу делать то, что вынамеревайтесь это сделать, просто удалите xs из начала вашего функционального тела:

def sum(xs: List[Int]): Int = {

Сейчас:

sum(List(1,3,2))
res0: Int = 6
...