Во-первых, ваш лучший вариант, как правило, в любом случае избегать такого рода конструкций и пытаться использовать вместо этого методы более высокого уровня (например, вы часто можете сделать 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 , это не плохой компромисс.