293 votes

Comment sortir une boucle dans la Scala ?

Comment puis-je sortir d'une boucle (pour le problème 4 du Projet Euler)?

var largest=0
for(i<-999 to 1 by -1) {
    for (j<-i to 1 by -1) {
        val product=i*j
        if (largest>product)
            // I want to break out here
        else
           if(product.toString.equals(product.toString.reverse))
              largest=largest max product
    }
}

Comment mettre des boucles for imbriquées dans la queue de la récursivité?

Scala Parler au FOSDEM 2009 http://www.slideshare.net/Odersky/fosdem-2009-1013261 le 22 page:

Break et continue Scala n'a pas. Pourquoi? Ils sont un peu impératif; une meilleure utilisation de nombreuses petites fonctions Question comment interagir avec les fermetures. Ils ne sont pas nécessaires!

Quelle est l'explication?

385voto

Rex Kerr Points 94401

Vous disposez de trois (ou plus) des options pour sortir de la boucle.

Supposons que vous souhaitez calculer la somme des nombres jusqu'à ce que le total est supérieur à 1000. Vous essayez

var sum = 0
for (i <- 0 to 1000) sum += i

sauf que vous voulez arrêter quand (somme > 1000).

Que faire? Il y a plusieurs options.

(1a) Utilisez construction qui comprend une condition que vous testez.

var sum = 0
(0 to 1000).toStream.takeWhile(_ => sum < 1000).foreach(i => sum+=i)

(1b) l'Utilisation de la queue de la récursivité au lieu d'une boucle for, profitant de combien il est facile d'écrire une nouvelle méthode en Scala:

var sum = 0
def addTo(i: Int, max: Int) {
  sum += i; if (sum < max) addTo(i+1,max)
}
addTo(0,1000)

(2) lève une exception.

object AllDone extends Exception { }
var sum = 0
try {
  for (i <- 0 to 1000) { sum += i; if (sum>=1000) throw AllDone }
} catch {
  case AllDone =>
}

(2a) En Scala 2.8+ c'est déjà pré-emballés, en scala.util.control.Breaks l'aide d'une syntaxe qui ressemble beaucoup à votre familier ancienne pause de C/Java:

import scala.util.control.Breaks._
var sum = 0
breakable { for (i <- 0 to 1000) {
  sum += i
  if (sum >= 1000) break
} }

(3) Mettre le code dans une méthode et l'utilisation de retour.

var sum = 0
def findSum { for (i <- 0 to 1000) { sum += i; if (sum>=1000) return } }
findSum

C'est intentionnellement fait de ne pas-trop-facile pour au moins trois raisons je pense. Tout d'abord, dans de grands blocs de code, il est facile de négliger "continuer" et "pause", ou de penser que vous êtes en rupture de plus ou de moins que vous êtes vraiment, ou à la nécessité de briser les deux boucles qui vous ne pouvez pas faire facilement de toute façon--donc l'usage standard, bien que pratique, a ses problèmes, et donc vous devriez essayer de structurer votre code d'une manière différente. Deuxièmement, Scala a toutes sortes d'imbrications que vous n'avez probablement pas le même avis, donc si vous pouviez sortir de choses, vous seriez probablement surpris par l'endroit où le flux de code clos (surtout avec des fermetures). Troisièmement, la plupart de la Scala de "boucles" ne sont pas vraiment normal boucles--ils sont les appels de méthode qui ont leur propre boucle, ou ils sont de récursivité qui peut ou peut ne pas être une boucle--et, bien qu'ils agissent looplike, il est difficile de trouver une manière cohérente, à savoir ce "break" et les comme devrait le faire. Donc, pour être cohérent, le plus sage chose à faire est de ne pas avoir un "break".

69voto

hohonuuli Points 709

Cela a changé en Scala 2.8, qui dispose d’un mécanisme pour les sauts. Vous pouvez maintenant faire ce qui suit :

39voto

Keith Blanchard Points 19

Il n’est jamais une bonne idée pour casser sur une boucle for. Si vous utilisez une boucle, cela signifie que vous savez combien de fois vous souhaitez effectuer une itération. Utiliser un certain temps boucle avec 2 conditions.

par exemple

13voto

Patrick Points 12559

Pour ajouter Rex Kerr répondez par un autre moyen :

  • (1c) vous pouvez également utiliser un garde dans votre boucle :

6voto

Ham Points 1956

Puisqu’il n’y a aucune dans Scala encore, vous pouvez essayer de résoudre ce problème avec l’aide un -déclaration. Par conséquent, vous devez mettre votre boucle interne dans une fonction, sinon le retour serait passer la boucle entière.

Scala 2.8 comprend toutefois un moyen de sortir

http://www.Scala-lang.org/API/RC/Scala/util/Control/breaks.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X