Прямая ссылка Scala на вложенную рекурсивную функцию

У меня есть это действительно простое определение метода с вложенной рекурсивной функцией:

def bar(arr : Array[Int]) : Int = {
  val foo : Int => Int = (i: Int) => if(i == 0) 0 else i + foo(i-1)
  foo(3)
}

Но я получаю эту ошибку:

<console>:36: error: forward reference extends over definition of value foo
     val foo : Int => Int = (i: Int) => if(i == 0) 0 else i + foo(i-1)
                                                              ^

Если я просто поставлю строку val foo: ... = ... саму по себе, а не вложенную в определение, все будет работать


person CJ Cobb    schedule 02.08.2015    source источник
comment
Почему бы тебе не сделать это дефом?   -  person Jus12    schedule 02.08.2015


Ответы (1)


Вы можете сделать это lazy val:

def bar(arr : Array[Int]) : Int = {
  lazy val foo : Int => Int = (i: Int) => if(i == 0) 0 else i + foo(i-1)
  foo(3)
}

or a def:

def bar(arr : Array[Int]) : Int = {
  def foo(i: Int): Int = if(i == 0) 0 else i + foo(i-1)
  foo(3)
}

Когда ты

поместите val foo: ... = ... строку отдельно, а не вложенную в определение

он становится комбинацией поля и метода получения, и foo(i-1) фактически вызывает метод получения вместо того, чтобы ссылаться на определяемое вами значение, что является незаконным; но когда у вас есть val внутри метода, это просто локальная переменная и не имеет метода получения.

person Alexey Romanov    schedule 02.08.2015