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