действительно ли возможно убежать из закрытия в отличном

Нет, они - то же. Но существует различие между:

Test t;      // create a Test called t

и

Test t();   // declare a function called t which returns a Test

Это - из-за основного C++ (и C) правило: Если что-то может возможно быть объявлением, то это - объявление.

Редактирование: Ре проблемы инициализации относительно POD и данных не-POD, в то время как я соглашаюсь со всем, что было сказано, я буду точно так же, как, чтобы указать, что эти проблемы только применяются, если вещь, являющаяся new'd или иначе созданный, не имеет пользовательского конструктора. Если будет такой конструктор, то это будет использоваться. Для 99,99% разумно разработанных классов будет такой конструктор, и таким образом, проблемы смогут быть проигнорированы.

26
задан 26 August 2009 в 18:43
поделиться

4 ответа

Вы можете выбросить исключение:

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

Используйте также "findAll" или "grep" для фильтрации вашего списка, а затем используйте "each".

[1, 2, 3].findAll{ it < 3 }.each{ println it }
8
ответ дан 28 November 2019 в 06:33
поделиться

12/05/2013 Сильно отредактировано.

Отвечая на заданный вопрос.

Можно ли выйти из закрытия?

Вы бы » break " из закрытия, введя ключевое слово return . Однако в приведенном примере это не помогает. Причина этого в том, что закрытие (воспринимайте его как метод) вызывается методом each для каждого элемента в коллекции.

Если вы запустите этот пример, вы увидите, что он напечатает 1 затем 3.

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

Почему break в контексте каждый не имеет смысла.

Чтобы понять, почему вы не можете вырваться из каждого как вы могли бы выйти из цикла 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, вы не можете прервать вызов или закрытие метода.

Что делать вместо того, чтобы прерывать каждый .

В Groovy вы должны выражать свой код, используя абстракции высокого уровня как таковые примитивный цикл не является идиоматическим. В приведенном вами примере я бы подумал об использовании findAll. Например:

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

Надеюсь, это поможет вам понять, что происходит.

Ответ на подразумеваемый вопрос.

Сможете ли вы прервать итерацию Collection.each против вашего предоставленного закрытия?

Вы не можете выйти из метода each , не выбрасывая и не перехватив исключение, как сказал Джон Вагенлейтнер.

14
ответ дан 28 November 2019 в 06:33
поделиться

Если вы используете InnoDB (или механизм хранения, который их поддерживает), вы можете использовать ограничения FOREIGN KEY для удаления соответствующих строк. Это один из самых простых и безопасных подходов, если вы не возражаете против небольшого влияния внешних ключей на производительность. Однако обратите внимание, что строки, удаленные из-за ограничений, не запускают триггеры.

В качестве альтернативы вы можете использовать триггеры. Они работают с любым механизмом хранения, и обычно их достаточно легко написать. Мне они нравятся, но они не очень производительны, если вы удаляете большое количество строк одновременно (несколько сотен или тысяч).

CREATE TRIGGER ad_orders AFTER DELETE ON orders
FOR EACH ROW DELETE FROM orders_items WHERE orderID = OLD.orderID;

Наконец, как было предложено в предыдущем ответе, вы можете использовать многотабличное DELETE:

8
ответ дан 28 November 2019 в 06:33
поделиться

Я часто забываю, что Groovy реализует любой метод.

[1, 2, 3].any
{   
   println it
   return (it == 2)
}​
22
ответ дан 28 November 2019 в 06:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: