在 Scala 中执行块 n 次是否有简短的语法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2842540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:08:41  来源:igfitidea点击:

Is there a brief syntax for executing a block n times in Scala?

scala

提问by Craig P. Motlin

I find myself writing code like this when I want to repeat some execution n times:

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

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

I'm looking for a shorter syntax like this:

我正在寻找更短的语法,如下所示:

n.times(doSomething())

Does something like this exist in Scala already?

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

EDIT

编辑

I thought about using Range's foreach() method, but then the block needs to take a parameter which it never uses.

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

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

采纳答案by missingfaktor

You could easily define one using Pimp My Library pattern.

您可以使用 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

回答by sblundy

The Range class has a foreach method on it that I think is just what you need. For example, this:

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

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

produced

产生

0
1
2
3
4
5

0
1
2
3
4
5

回答by Apocalisp

With scalaz 5:

使用scalaz 5

doSomething.replicateM[List](n)

With scalaz 6:

使用scalaz 6

n times doSomething

And that works as you would expect with most types (more precisely, for every monoid):

这与您对大多数类型的期望一样(更准确地说,对于每个 monoid):

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@36659c23

scala> res5.unsafePerformIO
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!

You could also say doSomething replicateM_ 5which only works if your doSomethingis an idiomatic value (see Applicative). It has better type-safety, since you can do this:

您也可以说doSomething replicateM_ 5这仅在您doSomething是惯用值时才有效(请参阅 参考资料Applicative)。它具有更好的类型安全性,因为您可以这样做:

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

but not this:

但不是这个:

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

Let me see you pull that off in Ruby.

让我看看你在 Ruby 中实现了这一点。

回答by huynhjl

I'm not aware of anything in the library. You can define a utility implicit conversion and class that you can import as needed.

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

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 just posted a similar answer while I was writing this...

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

回答by Adrian

It can be as simple as this:

它可以像这样简单:

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

回答by Less

def times(f: => Unit)(cnt:Int) :Unit = {
  List.fill(cnt){f}
}