Есть ли короткий синтаксис для выполнения блока n раз в Scala?
Я нахожу, что пишу такой код, когда хочу повторить некоторое выполнение n раз:
for (i <- 1 to n) { doSomething() }
Я ищу более короткий синтаксис, например:
n.times(doSomething())
Что-то вроде этого уже существует в Scala?
ИЗМЕНИТЬ
Я думал об использовании метода Range foreach(), но тогда блок должен принять параметр, который он никогда не использует.
(1 to n).foreach(ignored => doSomething())
Ответы
Ответ 1
Вы можете легко определить один, используя шаблон 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
Ответ 2
Класс Range имеет для него метод foreach, который, я думаю, является именно тем, что вам нужно. Например, это:
0.to(5).foreach(println(_))
произведено
0
1
2
3
4
5
Ответ 3
С scalaz 5:
doSomething.replicateM[List](n)
С scalaz 6:
n times doSomething
И это работает так, как вы ожидали бы с большинством типов (точнее, для каждого моноида):
scala> import scalaz._; import Scalaz._; import effects._;
import scalaz._
import Scalaz._
import effects._
scala> 5 times "foo"
res0: java.lang.String = 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] = <function1>
scala> res3(10)
res4: Int = 15
scala> 5 times putStrLn("Hello, World!")
res5: scalaz.effects.IO[Unit] = [email protected]
scala> res5.unsafePerformIO
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Вы также можете сказать doSomething replicateM_ 5
, который работает только в том случае, если ваш doSomething
является идиоматическим значением (см. Applicative
). Он имеет более безопасный тип безопасности, поскольку вы можете это сделать:
scala> putStrLn("Foo") replicateM_ 5
res6: scalaz.effects.IO[Unit] = [email protected]
но не это:
scala> { System.exit(0) } replicateM_ 5
<console>:15: error: value replicateM_ is not a member of Unit
Позвольте мне видеть, как вы это делаете в Ruby.
Ответ 4
Я ничего не знаю в библиотеке. Вы можете определить неявное преобразование и класс, которые вы можете импортировать по мере необходимости.
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"))
Рахул только что опубликовал аналогичный ответ, пока я писал это...
Ответ 5
Это может быть так просто:
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