is it possible to break out of closure in groovy

后端 未结 9 1898
醉梦人生
醉梦人生 2020-12-09 08:33

is there a way to \'break\' out of a groovy closure.

maybe something like this:

[1, 2, 3].each { 
  println(it)
  if (it == 2)
    break 
}
<         


        
相关标签:
9条回答
  • 2020-12-09 08:49

    I often forget that Groovy implements an "any" method.

    [1, 2, 3].any
    {   
       println it
       return (it == 2)
    }​
    
    0 讨论(0)
  • 2020-12-09 08:52

    Try to use any instead of each

    def list = [1, 2, 3, 4, 5, -1, -2]
    list.any { element ->
        if (element > 3)
        return true // break
        println element
    }
    

    The result : 1, 2, 3

    0 讨论(0)
  • 2020-12-09 08:53

    With rx-java you can transform an iterable in to an observable.

    Then you can replace continue with a filter and break with takeWhile

    Here is an example:

    import rx.Observable
    
    Observable.from(1..100000000000000000)
              .filter { it % 2 != 1} 
              .takeWhile { it<10 } 
              .forEach {println it}
    
    0 讨论(0)
  • 2020-12-09 08:54

    There is an other solution. Although, that groovy stuff like each/find/any is quite cool: if it doesn't fit, don't use it. You can still use the plain old

    for (def element : list)
    

    Especially, if you want to leave the method, too. Now you are free to use continue/break/return as you like. The resulting code might not be cool, but it is easy and understandable.

    0 讨论(0)
  • 2020-12-09 08:58

    You can throw an exception:

    try {
        [1, 2, 3].each { 
            println(it)
            if (it == 2)
                throw new Exception("return from closure") 
        }
    } catch (Exception e) { }
    

    Use could also use "findAll" or "grep" to filter out your list and then use "each".

    [1, 2, 3].findAll{ it < 3 }.each{ println it }
    
    0 讨论(0)
  • 2020-12-09 09:01

    12/05/2013 Heavily Edited.

    Answering the question that was asked.

    Is it possible to break out of a Closure?

    You would "break" out of a closure by issuing the return keyword. However that isn't helpful in the example that is given. The reason for this is that the closure (think of it as a method) is called by the each method for every item in the collection.

    If you run this example you will see it will print 1 then 3.

    [1, 2, 3].each {
      if (it == 2) return
      println(it)
    }
    

    Why break in the context of each doesn't make sense.

    To understand why you cannot break out of the each method like you could break out of a for loop you need to understand a bit of what is actually happening. Here is a gross simplification what the each method on a collection does.

    myEach([0,1,3])
    
    void myEach(List things) {
        for (i in things) {
            myEachMethod(i)
        }
    }
    
    void myEachMethod(Object it) { // this is your Closure
        if(it == 2) return
        println it
    }
    

    As you can see the closure is basically a method that can be passed around. Just as in java you cannot break from within method call or closure.

    What to do instead of breaking from each.

    In Groovy you are supposed to express your code using high level abstractions as such primitive looping is not idiomatic. For the example that you gave I would consider making use of findAll. For example:

    [1,2,3].findAll { it < 2 }.each { println it }
    

    I hope this helps you understand what is going on.

    Answering the implied question.

    Can you break out of the Collection.each iterations against your supplied closure?

    You cannot break out of the each method without throwing and catching an exception as John Wagenleitner has said. Although I would argue that throwing and catching an exception in the name of flow control is a code smell and a fellow programmer might slap your hands.

    0 讨论(0)
提交回复
热议问题