У вас есть три (или около того) варианта выхода из циклов.
Предположим, вы хотите суммировать числа, пока сумма не станет больше 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 на самом деле не являются обычными циклами - это вызовы методов, которые имеют свой собственный цикл, или они являются рекурсией, которая может на самом деле быть циклом, а может и не быть - и хотя они act петлеобразный, трудно придумать последовательный способ узнать, что должен делать «перерыв» и тому подобное. Поэтому, чтобы быть последовательным, мудрее всего не делать «перерыв».
Примечание : есть функциональные эквиваленты всего этого, где вы возвращаете значение sum
, а не изменяете его на месте. Это более идиоматические Scala. Однако логика остается прежней. (return
становится return x
и т. Д.).