Я бы ответил так, и я не уверен, достаточно ли это отличается от того, что говорили другие:
Поскольку вы можете перемещаться только внутри текущей области или в родительскую областьони намного менее опаснее, чем обычно подразумевается goto
, обратите внимание:
if (1) {
goto BAR;
die 'bar'
}
BAR:
Это должно сработать, очевидно, но это не сработает (не может двигаться вэто направление).
if (0) {
BAR:
die 'bar'
}
goto BAR;
Многие варианты использования labels
отличаются от goto тем, что они представляют собой просто более явные варианты управления потоком в активной зоне.Заявить, что они категорически хуже, означало бы, что:
LOOP: while (1) {
next LOOP if /foo;
}
чем-то хуже, чем
while (1) {
next if /foo/;
}
, что просто нелогично, если исключить стиль.Но, если говорить о стиле, последний вариант намного проще для чтения - и он не дает вам искать нужный ярлык.Читатель знает больше с next
(что вы перезапускаете цикл в текущей области видимости), и это лучше.
Давайте рассмотрим другой пример
while (1) {
while (1) {
last;
}
stuff;
}
-vs-
FOO: while (1) {
BAR: while (1) {
next FOO;
}
stuff;
}
В последнем примере здесь next FOO
, пропускает stuff
- вы можете этого пожелать, но это плохая идея.Это означает, что программист до конца прочитал родительскую область видимости, чего, вероятно, лучше избегать.Таким образом, label
не так плох, как goto
, и иногда они могут упростить код;но в большинстве случаев их следует избегать.Обычно я переписываю циклы без label
s, когда сталкиваюсь с ними на CPAN.