Нет, они - то же. Но существует различие между:
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% разумно разработанных классов будет такой конструктор, и таким образом, проблемы смогут быть проигнорированы.
Вы можете выбросить исключение:
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 }
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
, не выбрасывая и не перехватив исключение, как сказал Джон Вагенлейтнер.
Если вы используете InnoDB (или механизм хранения, который их поддерживает), вы можете использовать ограничения FOREIGN KEY для удаления соответствующих строк. Это один из самых простых и безопасных подходов, если вы не возражаете против небольшого влияния внешних ключей на производительность. Однако обратите внимание, что строки, удаленные из-за ограничений, не запускают триггеры.
В качестве альтернативы вы можете использовать триггеры. Они работают с любым механизмом хранения, и обычно их достаточно легко написать. Мне они нравятся, но они не очень производительны, если вы удаляете большое количество строк одновременно (несколько сотен или тысяч).
CREATE TRIGGER ad_orders AFTER DELETE ON orders
FOR EACH ROW DELETE FROM orders_items WHERE orderID = OLD.orderID;
Наконец, как было предложено в предыдущем ответе, вы можете использовать многотабличное DELETE:
Я часто забываю, что Groovy реализует любой метод.
[1, 2, 3].any
{
println it
return (it == 2)
}