12/05/2013 Сильно отредактировано.
Ответ на заданный вопрос.
Можно ли вырваться из замыкания?
Вы бы "сломали" из закрытия, введя ключевое слово return
. Однако это не помогает в приведенном примере. Причина этого заключается в том, что замыкание (представьте его как метод) вызывается методом each
для каждого элемента в коллекции.
Если вы запустите этот пример, вы увидите, что он напечатает 1, а затем 3.
[1, 2, 3].each {
if (it == 2) return
println(it)
}
Почему break
в контексте each
не имеет смысла.
Чтобы понять, почему вы не можете выйти из метода each
, как если бы вы могли выйти из цикла for
, вам нужно немного понять, что на самом деле происходит. Вот грубое упрощение того, что делает каждый метод в коллекции.
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
}
Как видите, замыкание - это в основном метод, который можно обойти. Как и в Java, вы не можете разорвать вызов метода или замыкание.
Что делать вместо взлома от each
.
В Groovy вы должны выражать свой код с помощью высокоуровневых абстракций, поскольку такие примитивные циклы не являются идиоматическими. Для примера, который вы привели, я бы рассмотрел использование findAll. Например:
[1,2,3].findAll { it < 2 }.each { println it }
Надеюсь, это поможет вам понять, что происходит.
Ответ на подразумеваемый вопрос.
Можете ли вы выйти из Collection.each
итераций против поставляемого замыкания?
Вы не можете выйти из метода each
, не бросив и не поймав исключение, как сказал Джон Вагенляйтнер. Хотя я бы сказал, что выбрасывание и перехват исключения во имя управления потоком - это запах кода, и один из программистов может хлопнуть вас по рукам.