Masz trzy (lub mniej więcej) opcje wyjścia z pętli.
Załóżmy, że chcesz sumować liczby, aż suma będzie większa niż 1000. Próbujesz
var sum = 0
for (i <- 0 to 1000) sum += i
z wyjątkiem tego, że chcesz zatrzymać kiedy (suma> 1000).
Co robić? Istnieje kilka opcji.
(1a) Użyj konstrukcji, która zawiera testowany warunek.
var sum = 0
(0 to 1000).iterator.takeWhile(_ => sum < 1000).foreach(i => sum+=i)
(ostrzeżenie - zależy to od szczegółów przeplatania testu takeWhile i foreach podczas oceny i prawdopodobnie nie powinno się go stosować w praktyce!).
(1b) Użyj rekurencji ogona zamiast pętli for, wykorzystując łatwość napisania nowej metody w Scali:
var sum = 0
def addTo(i: Int, max: Int) {
sum += i; if (sum < max) addTo(i+1,max)
}
addTo(0,1000)
(1c) Wróć do korzystania z pętli while
var sum = 0
var i = 0
while (i <= 1000 && sum <= 1000) { sum += 1; i += 1 }
(2) Rzuć wyjątek.
object AllDone extends Exception { }
var sum = 0
try {
for (i <- 0 to 1000) { sum += i; if (sum>=1000) throw AllDone }
} catch {
case AllDone =>
}
(2a) W Scali 2.8+ jest to już wstępnie spakowane przy scala.util.control.Breaks
użyciu składni, która wygląda bardzo podobnie do twojej starej starej przerwy w C / Java:
import scala.util.control.Breaks._
var sum = 0
breakable { for (i <- 0 to 1000) {
sum += i
if (sum >= 1000) break
} }
(3) Umieść kod w metodzie i użyj return.
var sum = 0
def findSum { for (i <- 0 to 1000) { sum += i; if (sum>=1000) return } }
findSum
Jest to celowo niezbyt łatwe z co najmniej trzech powodów, o których mogę myśleć. Po pierwsze, w dużych blokach kodu łatwo jest przeoczyć instrukcje „kontynuuj” i „zepsuć” lub myśleć, że wychodzisz z mniej lub bardziej niż naprawdę, lub musisz przerwać dwie pętle, których nie możesz zrobić i tak łatwo - więc standardowe użycie, chociaż przydatne, ma swoje problemy, dlatego powinieneś spróbować ustrukturyzować swój kod w inny sposób. Po drugie, Scala ma różnego rodzaju zagnieżdżenia, których prawdopodobnie nawet nie zauważasz, więc jeśli mógłbyś się wyrwać, prawdopodobnie byłbyś zaskoczony, gdzie skończył się przepływ kodu (szczególnie z zamknięciami). Po trzecie, większość „pętli” Scali nie jest tak naprawdę normalnymi pętlami - to wywołania metod, które mają swoją własną pętlę,Pętla, trudno jest znaleźć spójny sposób, aby wiedzieć, co powinno zrobić „zerwanie” i tym podobne. Aby być konsekwentnym, mądrzejszym rozwiązaniem jest wcale nie mieć „przerwy”.
Uwaga : Istnieją funkcjonalne odpowiedniki wszystkich tych funkcji, w których zwracana jest wartość sum
zamiast mutowania jej w miejscu. Są to bardziej idiomatyczne Scala. Jednak logika pozostaje taka sama. ( return
staje się return x
itp.).