Existe-t-il une courte syntaxe pour exécuter un bloc n fois dans Scala?

Je me trouve à écrire un code comme celui-ci quand je veux répéter une exécution n fois:

for (i <- 1 to n) { doSomething() } 

Je cherche une syntaxe plus courte comme celle-ci:

 n.times(doSomething()) 

Est-ce que quelque chose comme ça existe déjà à Scala?

MODIFIER

J’ai pensé à utiliser la méthode foreach () de Range, mais le bloc doit alors prendre un paramètre qu’il n’utilise jamais.

 (1 to n).foreach(ignored => doSomething()) 

Vous pouvez facilement en définir un en utilisant le modèle Pimp My Library.

 scala> implicit def intWithTimes(n: Int) = new { | def times(f: => Unit) = 1 to n foreach {_ => f} | } intWithTimes: (n: Int)java.lang.Object{def times(f: => Unit): Unit} scala> 5 times { | println("Hello World") | } Hello World Hello World Hello World Hello World Hello World 

La classe Range a une méthode foreach sur ce que je pense est juste ce dont vous avez besoin. Par exemple, ceci:

  0.to(5).foreach(println(_)) 

produit

0
1
2
3
4
5

Avec scalaz 5 :

 doSomething.replicateM[List](n) 

Avec scalaz 6 :

 n times doSomething 

Et cela fonctionne comme on s’y attend avec la plupart des types (plus précisément, pour chaque monoïde ):

 scala> import scalaz._; import Scalaz._; import effects._; import scalaz._ import Scalaz._ import effects._ scala> 5 times "foo" res0: java.lang.Ssortingng = foofoofoofoofoo scala> 5 times List(1,2) res1: List[Int] = List(1, 2, 1, 2, 1, 2, 1, 2, 1, 2) scala> 5 times 10 res2: Int = 50 scala> 5 times ((x: Int) => x + 1).endo res3: scalaz.Endo[Int] =  scala> res3(10) res4: Int = 15 scala> 5 times putStrLn("Hello, World!") res5: scalaz.effects.IO[Unit] = scalaz.effects.IO$$anon$2@36659c23 scala> res5.unsafePerformIO Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! 

Vous pourriez aussi dire doSomething replicateM_ 5 qui ne fonctionne que si votre doSomething est une valeur idiomatique (voir Applicative ). Il a une meilleure sécurité de type, puisque vous pouvez le faire:

 scala> putStrLn("Foo") replicateM_ 5 res6: scalaz.effects.IO[Unit] = scalaz.effects.IO$$anon$2@8fe8ee7 

mais pas ceci:

 scala> { System.exit(0) } replicateM_ 5 :15: error: value replicateM_ is not a member of Unit 

Laisse-moi te voir en Ruby.

Je ne suis au courant de rien dans la bibliothèque. Vous pouvez définir une conversion implicite d’utilitaire et une classe que vous pouvez importer selon vos besoins.

 class TimesRepeat(n:Int) { def timesRepeat(block: => Unit): Unit = (1 to n) foreach { i => block } } object TimesRepeat { implicit def toTimesRepeat(n:Int) = new TimesRepeat(n) } import TimesRepeat._ 3.timesRepeat(println("foo")) 

Rahul vient de poster une réponse similaire pendant que j’écrivais ceci …

Cela peut être aussi simple que cela:

 scala> def times(n:Int)( code: => Unit ) { for (i <- 1 to n) code } times: (n: Int)(code: => Unit)Unit scala> times(5) {println("here")} here here here here here