Има ли начин да излезете от @tailrec в Scala?

Имам метод, който е рекурсивен. Има ли начин в scala да излезе въз основа на размера на буфера (както е показано по-долу)? Случай за избухване, когато elementList.size > 5 например?

val elementList = ListBuffer.empty[Book]
@tailrec
def getBooks(elements: List[Element]) {
  elements match {
    case Nil => info("Reached end of elements list.")
    case element :: rest if element.getElementType == ElementType.BOOK => {
      elementList.append(element.getBook) 
      getLooks(rest)
    }
    case _ => getBooks(elements.tail)
  }
}

person user786045    schedule 07.06.2013    source източник
comment
обмислете използването на стандартни функции като elements.filter(_.getElementType==ElementType.BOOK).take(5)   -  person vitalii    schedule 07.06.2013
comment
Можете да използвате ядрената опция и да напишете return.   -  person janm399    schedule 07.06.2013


Отговори (2)


Предполагам, че най-простият начин би бил просто да обвиете if израз около вашия match израз по следния начин:

val elementList = ListBuffer.empty[Book]
@tailrec
def getBooks(elements: List[Element]) {
  if (elementList.size <= 5){
    elements match {
      case Nil => info("Reached end of elements list.")
      case element :: rest if element.getElementType == ElementType.BOOK => {
        elementList.append(element.getBook) 
        getLooks(rest)
      }
      case _ => getBooks(elements.tail)
    }
  }
}
person cmbaxter    schedule 07.06.2013
comment
Като алтернатива може да добави допълнително case xs if elementList.size > 5 => () - person Luigi Plinge; 07.06.2013

Най-общо казано, можете да опитате да предадете броя на оставащите елементи в рекурсията.

Например:

  def get(list: List[Int], max: Int): List[Int] = {

    @tailrec
    def get(list: List[Int], acc: List[Int], remaining: Int): List[Int] = {
      list match {

        case h :: tail if remaining > 0 =>
          get(tail, h :: acc, remaining - 1)

        case _ =>
          acc
      }
    }

    // Requires reverse() !
    get(list, Nil, max).reverse

Що се отнася до акумулатора: вместо това можете да използвате буфер, за да предотвратите reverse() в края.

person Beryllium    schedule 07.06.2013