У вас есть три (или около того) варианта вырваться из петель.
Предположим, вы хотите суммировать числа, пока сумма не станет больше 1000. Вы пытаетесь
var sum = 0
for (i <- 0 to 1000) sum += i
кроме того, что вы хотите остановить, когда (сумма> 1000).
Что делать? Есть несколько вариантов.
(1a) Используйте некоторую конструкцию, включающую проверяемое условие.
var sum = 0
(0 to 1000).iterator.takeWhile(_ => sum < 1000).foreach(i => sum+=i)
(предупреждение - это зависит от деталей того, как тест takeWhile и foreach чередуются во время оценки, и, вероятно, не должны использоваться на практике!).
(1b) Используйте хвостовую рекурсию вместо цикла for, используя преимущества того, как легко написать новый метод в Scala:
var sum = 0
def addTo(i: Int, max: Int) {
sum += i; if (sum < max) addTo(i+1,max)
}
addTo(0,1000)
(1c) Возврат к использованию цикла while
var sum = 0
var i = 0
while (i <= 1000 && sum <= 1000) { sum += 1; i += 1 }
(2) Брось исключение.
object AllDone extends Exception { }
var sum = 0
try {
for (i <- 0 to 1000) { sum += i; if (sum>=1000) throw AllDone }
} catch {
case AllDone =>
}
(2a) В Scala 2.8+ это уже предварительно упаковано с scala.util.control.Breaks
использованием синтаксиса, который очень похож на ваш знакомый старый перерыв в C / Java:
import scala.util.control.Breaks._
var sum = 0
breakable { for (i <- 0 to 1000) {
sum += i
if (sum >= 1000) break
} }
(3) Поместите код в метод и используйте return.
var sum = 0
def findSum { for (i <- 0 to 1000) { sum += i; if (sum>=1000) return } }
findSum
Это намеренно сделано не слишком легко по крайней мере по трем причинам, которые я могу придумать. Во-первых, в больших блоках кода легко пропустить операторы «continue» и «break», или думать, что вы выбиваете больше или меньше, чем вы есть на самом деле, или вам нужно разбить два цикла, которые вы не можете сделать в любом случае это легко - поэтому стандартное использование, хотя и удобно, имеет свои проблемы, и поэтому вы должны попытаться структурировать свой код по-другому. Во-вторых, в Scala есть все виды вложений, которые вы, вероятно, даже не замечаете, поэтому, если вы можете разорвать все вокруг, вы, вероятно, будете удивлены тем, где закончился поток кода (особенно с замыканиями). В-третьих, большинство «циклов» Scala на самом деле не являются обычными циклами - это вызовы методов, которые имеют свой собственный цикл,петлеобразно, трудно придумать последовательный способ узнать, что должен делать «перерыв» и тому подобное. Поэтому, чтобы быть последовательным, разумнее всего не иметь «перерыва».
Примечание : есть функциональные эквиваленты всех этих, где вы возвращаете значение, sum
а не изменяете его на месте. Это более идиоматические Scala. Однако логика остается прежней. ( return
становится return x
и т. д.).