scala代码中的Stackoverflow错误

时间:2016-11-25 13:23:00

标签: scala

在这段代码中,我试图将两棵树联合起来,如下所示:

class NonEmpty(elem: Tweet, left: TweetSet, right: TweetSet) extends TweetSet {

    def union(that: TweetSet): TweetSet =
    {
      def unionRec(set:TweetSet,acc:TweetSet): TweetSet =
      {
        if (set.isEmpty)
          return acc
        else
          return unionRec(right,unionRec(left,acc.incl(elem)))
      }
      unionRec(this,that)
    }

    def isEmpty: Boolean = false

    def incl(x: Tweet): TweetSet = {
      if (x.text < elem.text) new NonEmpty(elem, left.incl(x), right)
      else if (elem.text < x.text) new NonEmpty(elem, left, right.incl(x))
      else this
    }

}

class Empty extends TweetSet {
  def isEmpty: Boolean = true
}

但是当我尝试执行union方法时,我收到stackOverflow错误:

java.lang.StackOverflowError
    at scala.collection.immutable.StringLike$class.compare(StringLike.scala:74)
    at scala.collection.immutable.StringOps.compare(StringOps.scala:30)
    at scala.collection.immutable.StringOps.compare(StringOps.scala:30)
    at scala.math.Ordered$class.$less(Ordered.scala:76)
    at scala.collection.immutable.StringOps.$less(StringOps.scala:30)
    at objsets.NonEmpty.incl(TweetSet.scala:235)
    at objsets.NonEmpty.incl(TweetSet.scala:236)
    at objsets.NonEmpty.incl(TweetSet.scala:235)
    at objsets.NonEmpty.incl(TweetSet.scala:236)
    at objsets.NonEmpty.incl(TweetSet.scala:235)
    at objsets.NonEmpty.incl(TweetSet.scala:235)
    at objsets.NonEmpty.incl(TweetSet.scala:236)
    at objsets.NonEmpty.incl(TweetSet.scala:236)
    at objsets.NonEmpty.incl(TweetSet.scala:235)

为什么会这样?

2 个答案:

答案 0 :(得分:1)

对于最终终止的递归,您需要确保unionRec的第一个参数中的树迟早是空的。 由于你总是左右调用它,你的递归永远不会终止。

答案 1 :(得分:-2)

你有unionRec方法巫婆是递归的。显然它调用了太多次,实际上导致了堆栈溢出。

要修复它,你应该重新编写它以使尾递归。 Scala将这种递归表示为一个简单的循环。

使用@tailrec注释注释您的方法,以确保它满足尾递归要求。