в случае рекурсивной функции nil не выполняется - PullRequest
1 голос
/ 20 марта 2020

У меня есть рекурсивная функция, но регистр Nil => не работает, и у меня есть StackOverflowError. Я не понимаю, почему он не перехватывает Nil после того, как хвост всегда передается в функцию, он должен быть пустым в какой-то момент.

    def parser(lex: List[Any], acc: Int, myTree: ListBuffer[Any]): Any = lex match {
    case Nil => this.tree += myTree // inside class attached created new list.
    case (x: Tokens) :: xs =>
      if (x.getType == "variable") {
        println("count variable type found: " + (acc + 1))
        var nextEle = getElement(acc + 1)
        nextEle.getValue match {
          case "=" => myTree += new Node("assignment", x.getValue, getElement(acc + 2).getValue)
          case "<" => myTree += new Node(nextEle.getValue.toString, x.getValue, getElement(acc + 2).getValue)
          case _ =>
        }
        //myTree += new Node(x.getType, x.getValue, null)
      }
      parser(xs, acc + 1, myTree)
    }

1 Ответ

2 голосов
/ 20 марта 2020

Этот метод не может быть оптимизирован компилятором до al oop, поэтому он помещает данные в стек для каждого рекурсивного вызова. Вы всегда должны аннотировать методы, которые должны быть оптимизированы таким образом, чтобы убедиться, что это действительно происходит. Аннотируйте с помощью @annotation.tailrec, чтобы убедиться, что компилятор действительно не использует стек для рекурсивных вызовов.

Чтобы исправить это, установите метод либо private, либо final.

@annotation.tailrec
final def parser(lex: List[Any], acc: Int, myTree: ListBuffer[Any]) ...
* 1008. *

Использование Any здесь также вызывает беспокойство. Код не будет работать, если lex не равен List[Tokens], так почему бы не указать это в сигнатуре функции? И myTree выглядит как ListBuffer[Node].

...