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

问题描述 投票:0回答:6

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

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

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

n.times(doSomething())

Scala 中已经存在这样的东西了吗?

编辑

我考虑过使用 Range 的 foreach() 方法,但是块需要采用一个它从未使用过的参数。

(1 to n).foreach(ignored => doSomething())
scala
6个回答
56
投票

您可以轻松地将一个方法定义为扩展方法:

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

46
投票

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

 (1 to 5).foreach(println)

产生

1
2
3
4
5


22
投票

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

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

但不是这个:

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

让我看看您如何用 Ruby 实现这一目标。


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"))

当我写这篇文章时,拉胡尔刚刚发布了类似的答案......


2
投票

它可以像这样简单:

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

0
投票
def times(f: => Unit)(cnt:Int) :Unit = {
  List.fill(cnt){f}
}
© www.soinside.com 2019 - 2024. All rights reserved.