Elegant way for do … while in groovy

て烟熏妆下的殇ゞ 提交于 2019-11-30 06:02:32

So many answers and not a single one without a redundant call, a shame ;)

This is the closest it can get to purely language syntax based do-while in Groovy:

while ({
    x.doIt()
    !x.isFinished()
}()) continue

The last statement within curly braces (within closure) is evaluated as a loop exit condition.

Instead of continue keyword a semicolon can be used.

Additional nice thing about it, loop can be parametrized (kind of), like:

Closure<Boolean> somethingToDo = { foo ->
    foo.doIt()
    !foo.isFinished()
}

and then elsewhere:

while (somethingToDo(x)) continue

Formerly I've proposed this answer over here: How do I iterate over all bytes in an inputStream using Groovy, given that it lacks a do-while statement?

Steve Sowerby

You can roll your own looping that's almost what you want. Here's an example with loop { code } until { condition } You can't have a corresponding loop { code } while { condition } because while is a keyword. But you could call it something else.

Anyway here's some rough and ready code for loop until. One gotcha is you need to use braces for the until condition to make it a closure. There may well be other issues with it.

class Looper {
   private Closure code

   static Looper loop( Closure code ) {
      new Looper(code:code)
   }

   void until( Closure test ) {
      code()
      while (!test()) {
         code()
      }
   }
}

Usage:

import static Looper.*

int i = 0
loop {
   println("Looping : "  + i)
   i += 1
} until { i == 5 }
tim_yates

Depending on your use case, there are options like this: do .. while() in Groovy with inputStream?

Or you can do:

x.doIt()
while( !x.finished ) { x.doIt() }

Or

while( true ) {
    x.doIt()
    if( x.finished ) break
}

You can use a condition variable with the regular while loop:

def keepGoing = true
while( keepGoing ){
    doSomething()
    keepGoing = ... // evaluate the loop condition here
}

Update Groovy 2.6 has been abandoned to concentrate on 3.0.

From Groovy 2.6 on, do-while is supported when enabling the new Parrot Parser, from Groovy 3.0 on this is the default. See release notes:

// classic Java-style do..while loop
def count = 5
def fact = 1
do {
    fact *= count--
} while(count > 1)
assert fact == 120

Or you can implement it in a Groovier way :

def loop(Closure g){
    def valueHolder = [:]
    g.delegate = valueHolder
    g.resolveStrategy = Closure.DELEGATE_FIRST
    g()
    [until:{Closure w ->
        w.delegate = valueHolder
        w.resolveStrategy = Closure.DELEGATE_FIRST
        while(!w()){
        g()
        }
        }]
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!