在Scala中执行块n次有一个简短的语法吗?

Cra*_*lin 50 scala

当我想重复执行n次时,我发现自己编写了这样的代码:

for (i <- 1 to n) { doSomething() }
Run Code Online (Sandbox Code Playgroud)

我正在寻找这样一个更短的语法:

n.times(doSomething())
Run Code Online (Sandbox Code Playgroud)

Scala中是否存在类似的内容?

编辑

我想过使用Range的foreach()方法,但是块需要采用它从未使用过的参数.

(1 to n).foreach(ignored => doSomething())
Run Code Online (Sandbox Code Playgroud)

mis*_*tor 51

您可以使用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
Run Code Online (Sandbox Code Playgroud)

  • 它实际上已添加(https://lampsvn.epfl.ch/trac/scala/changeset/18599/scala/trunk/src/library/scala/runtime/RichInt.scala),但删除后不久(https:// lampsvn .epfl.ch/TRAC /阶/变更/ 18648 /阶/中继/ SRC /库/阶/运行/ RichInt.scala).Quoth extempore:"这是最好的时代......这是时代的逆转......".将内容添加到标准库可能会破坏现有代码,必须相当谨慎地完成. (9认同)
  • 我很想将"时代"添加到RichInt. (6认同)

sbl*_*ndy 36

Range类有一个foreach方法,我认为这正是你需要的.例如,这个:

 0.to(5).foreach(println(_))
Run Code Online (Sandbox Code Playgroud)

生成

0
1
2
3
4
5

  • `0到5 foreach println`看起来更干净. (11认同)
  • 另外:`7到11 foreach {println(_)}` (4认同)

Apo*_*isp 21

使用scalaz 5:

doSomething.replicateM[List](n)
Run Code Online (Sandbox Code Playgroud)

使用scalaz 6:

n times doSomething
Run Code Online (Sandbox Code Playgroud)

这可以像你期望的那样适用于大多数类型(更确切地说,对于每个幺半群):

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] = scalaz.effects.IO$$anon$2@36659c23

scala> res5.unsafePerformIO
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Run Code Online (Sandbox Code Playgroud)

你也可以说doSomething replicateM_ 5只有你doSomething的惯用价值才能起作用(见Applicative).它具有更好的类型安全性,因为您可以这样做:

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

但不是这个:

scala> { System.exit(0) } replicateM_ 5
<console>:15: error: value replicateM_ is not a member of Unit
Run Code Online (Sandbox Code Playgroud)

让我看看你在Ruby中取消它.

  • @Apocalisp我并不总是做IO,但是当我这样做时,我会用monad做 (3认同)
  • 这些天我正在做一些IO,我是在monad中做的. (2认同)

huy*_*hjl 5

我不知道图书馆里有什么.您可以定义可以根据需要导入的实用程序隐式转换和类.

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"))
Run Code Online (Sandbox Code Playgroud)

Rahul在写这篇文章时刚刚发布了类似的答案......