GOTO, который все еще рассматривают вредным? [закрытый]

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

273
задан 16 revs, 10 users 71% 22 July 2016 в 09:28
поделиться

44 ответа

В то время как я думаю, лучше избегать goto почти на любой ситуации, существуют исключения. Например, одно место, которое я видел, где операторы перехода являются изящным решением по сравнению с другими намного более замысловатые пути, реализует последний вызов elimintation для интерпретатора.

2
ответ дан mweiss 23 November 2019 в 02:12
поделиться

Основная идея состоит в том, что goto дает Вам слишком много свободы сделать что-то, что Вы не намеревались. Это может вызвать ошибки в местах, которые, кажется, не связаны с оператором перехода, таким образом, это делает обслуживание кода более трудным. Если Вы думаете, что Вам нужен оператор перехода, Вы неправы:) и необходимо вместо этого заново продумать конструкцию кода. Поэтому современные языки программирования приложили много сил для предоставления Вам читаемые, удобные в сопровождении конструкции управления потоком и механизмы обработки исключений.

я также собираюсь не согласиться с lassevk. Так как goto злоупотребляют больше, чем правильно используемый, я полагаю, что он не имеет никакого места на хорошо разработанном языке. Даже для "идеального" использования goto, другие способы сделать его, которые требуют, больше кода должно быть предпочтено.

Так, таким образом, да это все еще считают вредным.

1
ответ дан 2 revs 23 November 2019 в 02:12
поделиться

У меня только есть потребность в нем в Основном (т.е. VB, VBScript, и т.д.) и пакетные файлы. Я тогда только использую его для обработки ошибок. В Основном я ухаживаю только за использованием "на ошибке goto". В пакетных файлах я должен использовать его, потому что еще нет команда. Я тогда только использую их как вперед переходы к значимым маркировкам.

1
ответ дан bruceatk 23 November 2019 в 02:12
поделиться

Используя goto делает слишком легким записать "запутанный код", который не особенно удобен в сопровождении. Самое важное правило следовать состоит в том, чтобы записать читаемый код, но конечно это зависит от того, каковы цели проекта. Поскольку "лучшая практика", избегающая goto, является хорошей идеей. Это - что-то, что типы экстремального программирования назвали бы "запахом кода", потому что это указывает, что можно делать что-то не так. Используя повреждение, в то время как цикличное выполнение удивительно подобно goto, кроме него, не goto, но снова признак, что код не может быть оптимальным. Поэтому, я верю, также важно не найти более современные лазейки программирования, которые являются по существу goto другим именем.

1
ответ дан srclontz 23 November 2019 в 02:12
поделиться

Однажды, рано в моей жизни программирования, я произвел программу, которая состояла из серии функций в цепочке, где каждая функция, вызванная ее преемник, данный успешные условия и завершения.

Это был отвратительный cludge, который имел несколько серьезных проблем, самое серьезное существо, которое не могла завершить никакая функция, пока все функции под ним не завершились.

, Но это было быстро разработано, работал хорошо на ограниченный набор проблем, которые это было разработано для решения и было, показал логику и поток программы явно, которая работала хорошо, когда я осуществил рефакторинг и расширил его для включения в другой проект.

Мой голос по использованию это, когда это имеет смысл и осуществляет рефакторинг его как только его удобное.

1
ответ дан J.T. Hurley 23 November 2019 в 02:12
поделиться

Посмотрите это , это хорошее использование GoTo, но на языке с сборщиком мусора I думаю, единственная причина использовать GoTo - это запутать ваш код (инструменты для запутывания используют GoTo, чтобы скрыть свой код)

0
ответ дан Nicolas Dorier 23 November 2019 в 02:12
поделиться

Да, GOTO все еще считается вредным. К тому времени, когда вы окажетесь в редкой ситуации, когда использование GOTO может быть допустимым, вы должны быть достаточно уверены в своих собственных навыках программирования, чтобы не нуждаться в проверке других. Любые GOTO-подобные функции, которые позволяют вам прыгать даже дальше, чем разрешено GOTO, следует считать более опасными, чем GOTO.

3
ответ дан 23 November 2019 в 02:12
поделиться

Вычисленные gotos для диспетчеризации часто легче понять, чем очень большой оператор switch.

Для ошибок и сопутствующих потоков я считаю, что setcontex или setjmp (где доступны) «лучше».

0
ответ дан 23 November 2019 в 02:12
поделиться

Использование GOTO может быть полезным при генерации конечных автоматов C. Я бы никогда не использовал GOTO в написанном от руки коде - «современные» языковые конструкции делают его совершенно ненужным.

Конструкция setjmp / longjmp может быть полезна в определенных обстоятельствах (когда отсутствуют «истинные» исключения или когда вы реализуете что-то вроде схемы Цыпленка), но ей нет места в "обычном" программировании.

0
ответ дан 23 November 2019 в 02:12
поделиться

В идеальном мире нам никогда бы не понадобился GOTO. Однако мы живем в несовершенном мире. У нас нет компиляторов с каждой структурой управления, о которой мы можем мечтать. Иногда мне кажется, что лучше использовать GOTO, чем класть управляющую структуру, которой на самом деле не существует.

Самая распространенная (не то чтобы обычная) - это конструкция с половиной цикла. Вы всегда выполняете первую часть, возможно, вы выполняете остальную часть, а затем возвращаетесь и снова выполняете первую часть. Конечно, вы можете реализовать это с помощью логического флага внутри цикла while, но мне не нравится этот ответ, потому что он, на мой взгляд, менее ясен. Когда вы видите что-то вроде:

loop:
  GetSomeData;
  if GotData then
     Begin
        ProcessTheData;
        StoreTheResult;
        Goto Loop;
     End;

для меня это яснее, чем

Repeat
  GetSomeData;
  Flag := GotData;
  if Flag then
    Begin
      ProcessTheData;
      StoreTheResult;
    End;
Until Not Flag;

, и бывают случаи, когда

Function GotTheData;

Begin
  GetSomeData;
  Result := GotData;
End;

While GotTheData do
  Begin
    ProcessTheData;
    StoreTheResult;
  End;

не работает, и я твердо верю, что код должен быть ясным.

0
ответ дан 23 November 2019 в 02:12
поделиться

Многие современные языки программирования используют свой компилятор для наложения ограничений на использование GOTO. - это снижает потенциальные риски. Например, C # не позволит вам использовать GOTO для перехода в тело цикла извне. Ограничения упоминаются в документации .

Это один из примеров того, как GOTO иногда безопаснее, чем раньше.

В некоторых случаях использование GOTO аналогично раннему возврату из функции (т. Е. Досрочному выходу из цикла). Однако о хорошей форме можно поспорить.

1
ответ дан 23 November 2019 в 02:12
поделиться

На мой взгляд, «вредный переход» больше связан с инкапсуляцией и согласованностью состояния, чем с чем-либо еще.

Большая часть кода, даже «oo», имеет такую ​​же плохую инкапсуляцию состояния, как и любой другой спагетти-код.

Проблема с «goto, который считается вредным» заключается в том, что он оставляет программисту, который смотрит только на механистическое правило, без понимания впечатления, что единственным элементом управления потоком, который должен быть доступен, является метод возврата, и это очень легко приводит к передаче много говорится по ссылке - и , что ведет прямо к отсутствию инкапсуляции состояния, той самой вещи, от которой «goto посчитал вредным» пытался избавиться.

Проследите за потоком управления в типичной кодовой базе «объектно-ориентированного подхода» и скажите мне, что у нас все еще нет кода спагетти .... (кстати, я не имею в виду код «равиоли», который обычно получает так много ненавижу - путь выполнения кода равиоли обычно довольно прост, даже если отношения между объектами не очевидны сразу).

Или, говоря другими словами, отказ от gotos в пользу того, чтобы все было подпрограммой, полезно только в том случае, если каждая подпрограмма изменяет только локальное состояние, которое не может быть изменено, кроме как с помощью этой подпрограммы (или, по крайней мере, этого объекта).

1
ответ дан 23 November 2019 в 02:12
поделиться

Есть несколько проблем с goto. Во-первых, трудно увидеть, как идет код. Блок if легче увидеть из-за фигурных скобок, но goto скрывает это от вас. Кроме того, while и if также по сути являются gotos, но они помогают объяснить, почему вы прыгаете взад и вперед в своем коде. С обычным goto, который нужно собрать самостоятельно.

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

Если вы собираетесь работать над этим кодом, я бы порекомендовал написать несколько модульных тестов и переписать его. В противном случае просто позвольте этому быть.

Все, что было сказано, иногда по соображениям производительности «может» быть уместным использовать goto.

1
ответ дан 23 November 2019 в 02:12
поделиться

Дело не в том, что goto сам по себе плох; дело в том, что использование goto, когда ту же логику можно более четко выразить по-другому, плохо. Это может затруднить выполнение кода и затруднить обслуживание. Просто зайдите и посмотрите в качестве примера некоторые программы на Basic из старых плохих времен.

На мой взгляд, в современном языке, таком как C #, в обычных обстоятельствах никогда не должно быть необходимости в goto. Если я обнаружил, что использую его, это обычно знак того, что мне нужно переосмыслить свою логику - почти наверняка есть более четкий способ выразить тот же код с помощью обычных операторов потока кода.

Тем не менее, существуют специальные цели, для которых goto может быть чрезвычайно полезным (и меня раздражают языки, в которых его нет). Я в основном использую его в C для выхода из нескольких уровней циклов или для обработки ошибок; Я считаю, что у C # есть языковые особенности, которые означают, что вам не нужно этого делать. (Это также действительно полезно при создании автогенерированного кода, но это не то, с чем большинство людей сталкивается в реальной жизни.)

Есть еще одна проблема с goto, которая носит чисто политический характер: многие люди ненавидят его и используют его в коде, , даже если он оправдан , может вызвать проблемы. Если это код назначения, то да, перепишите его, иначе вы, вероятно, получите пометку.В противном случае я был бы склонен оставить это до следующего раза, когда вам нужно будет провести техническое обслуживание в этом разделе.

1
ответ дан 23 November 2019 в 02:12
поделиться
Другие вопросы по тегам:

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