Переход к началу цикла for в программе Scala - PullRequest
3 голосов
/ 04 июня 2011

В цикле for в моем коде Scala я хочу перейти к началу цикла и не выполнять следующие инструкции, если определенное условие выполняется.В Java я могу использовать «продолжить» для этого.Но «продолжить», похоже, не работает в Scala.Итак, как мне перейти к началу цикла в программе Scala?

Пожалуйста, помогите Спасибо.

Ответы [ 2 ]

7 голосов
/ 04 июня 2011

Во-первых, ваш лучший вариант, как правило, в любом случае избегать такого рода конструкций и пытаться использовать вместо этого методы более высокого уровня (например, вы часто можете сделать xs.map(doSomeStuff).filter(condition).foreach(doConditionalStuff)). Это не всегда практично, но гораздо чаще, чем вы могли изначально подозревать. Тем не менее, проблема остается в тех случаях, когда продолжить полезно: очень длинная серия охранников в длинном блоке кода, которая не может быть логически разбита на части.

continue - сложная языковая конструкция для языка с анонимными функциями. Одна из причин практична: анонимная функция - это функция, и вы не можете легко вернуться к некоторому циклу, который ее вызывает, просто выполнив переход. Другая причина концептуальна: если вы используете метод map, который сам по себе является своего рода циклом, куда именно continue может вернуть вас в начало?

Вместо того, чтобы иметь дело с этими неуклюжими случаями, Scala предоставляет (как библиотечную функцию, основанную на исключениях) конструкцию breakable, которая явно указывает, где вы хотите разбить:

import scala.util.control.Breaks._
breakable {
  for (i <- 1 to 10) {
    if (i>3) break
    println(i)
  }
}

Но поскольку это универсальная конструкция, вы можете использовать ее и внутри цикла for:

import scala.util.control.Breaks._
for (i <- 1 to 10) {
  breakable {
    if ((i%2)==0) break
    println(i)
  }
}

Вы даже можете перейти на несколько уровней, если создадите свои собственные классы перерыва. Вот пример симуляции цикла for с break и continue:

val outer,inner = new scala.util.control.Breaks
outer.breakable {
  for (i <- 1 to 10) {
    inner.breakable {
      if ((i%2)==0) inner.break
      if (i>3) outer.break
      println(i)
    }
  }
}

И если вы часто используете этот шаблон, вы можете изменить свой импорт, чтобы сделать его лучше:

// Do this once at the top of the file
import scala.util.control.Breaks._
object Continued extends scala.util.control.Breaks {}
import Continued.{break=>continue, breakable=>continuing}

// Now every time you need it:
breakable{ for (i <- 1 to 10) continuing {
  if ((i%2)==0) continue
  if (i>3) break
  println(i)
}}

Печатать немного больше, если вам действительно нужна эта функциональность, но, учитывая, как бессмысленные разрывы и продолжения находятся в контексте другой очень полезной функциональности, которую имеет Scala , это не плохой компромисс.

5 голосов
/ 04 июня 2011

Если вы используете Scala 2.7, из http://www.scala -lang.org / node / 257

Эти ключевые слова не включены в Scala 2.7 и должны быть реализованы другим способом. Для разрыва самое простое, что нужно сделать, это разделить ваш код на более мелкие методы и использовать return для досрочного выхода. Для продолжения простой подход - поместить пропущенные части цикла в if. Scala 2.8 будет включать в себя перерыв, но не продолжать.

Если вы используете Scala 2.8

import util.control.Breaks._
// for continue, write this somewhere in your program
val continue = new Breaks
/* use like */
Breaks.breakable {
  for (i <- 1 to 10)
  continue.breakable { if (i % 2 == 0) continue.break; println(i); if (i == 7) Breaks.break }
}


//source http://daily-scala.blogspot.com/2010/04/breaks.html

Обратите внимание, что обычно требующие break и continue означают, что вы не настолько функциональны, как хотелось бы Scala.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...