代码之家  ›  专栏  ›  技术社区  ›  Craig P. Motlin

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

  •  48
  • Craig P. Motlin  · 技术社区  · 14 年前

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

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

    我在找一个像这样简短的语法:

    n.times(doSomething())
    

    这样的东西在斯卡拉已经存在了吗?

    编辑

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

    (1 to n).foreach(ignored => doSomething())
    
    5 回复  |  直到 7 年前
        1
  •  49
  •   missingfaktor Kevin Wright    14 年前

    您可以使用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
  •  33
  •   sblundy    14 年前

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

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

    产生






        3
  •  21
  •   Apocalisp    7 年前

    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
    

    让我看看你用红宝石做的。

        4
  •  5
  •   huynhjl bhericher    14 年前

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

    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发表了一个类似的答案…

        5
  •  2
  •   Adrian keiter    13 年前

    可以这么简单:

    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