Разве это плохо, если оставить все как есть? - PullRequest
3 голосов
/ 05 марта 2011

Скажем, у вас есть только ограниченное число возможных условий, давайте назовем их a, b, c, d, и вы абсолютно уверены, что любые другие возможности невозможны.

Это лучше сделать

if(a)
  do_something();
else if(b)
  do_something();
else if(c)
  do_something();
else if(d)
  do_something();

или

if(a)
  do_something();
if(b)
  do_something();
if(c)
  do_something();
else
  do_something();

Ответы [ 7 ]

2 голосов
/ 05 марта 2011

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

1 голос
/ 05 марта 2011

Нет «лучшего» пути, все зависит от того, как должен проходить поток управления.

if(a)
  do_something();
else if(b)
  do_something();
else if(c)
  do_something();
else if(d)
  do_something();

Это ветвящийся поток управления , означающий, что ifбудет проверен в порядке первого появления, а первое из найденных с оценкой true будет выбрано и выполнено среди всех условий, все остальные будут пропущены.

if(a)
  do_something();
if(b)
  do_something();
if(c)
  do_something();
else
  do_something();

Это последовательность управляющий поток (хотя ваш последний if является ветвящимся), что означает, что будет проверен весь блок if, а каждый оцененный в true будет выбран и выполнен.(Хотя последний, как если бы c был ложным, будет выполнен только блок else.)

Выбор того, какой использовать, полностью зависит от того, что должно быть выполнено.Что касается блоков switch, они в основном являются ярлыками для потока управления ветвлением, а обычно ведут себя точно так же после компиляции, однако это не обязательно верно (т. Е. Когда не используется break или какой-либо языкподдержка goto другой случай и т. д.), но это выходит за рамки.

1 голос
/ 05 марта 2011

Я бы пошел с первым, но с утверждением или чем-то подобным в дополнительном блоке else.

if(a)
  do_something();
else if(b)
  do_something();
else if(c)
  do_something();
else if(d)
  do_something();
else
  assert(0); // or throw ImpossibleException or whatever

(это предложение относится также к switch блокам с меткой default)

Даже если вы предполагаете, что это невозможно, в общем, все же хорошей практикой «глубокоэшелонированной защиты» является дополнительная проверка: иногда вы можете изменить свое приложение в другом месте, чтобы возможные варианты стали больше (типичный случай добавляет значение enum) и забудьте об обновлении этой части кода; без такой проверки у вас есть ошибка, которая может оставаться незамеченной долгое время.

1 голос
/ 05 марта 2011

Стандартный метод для этого - использовать оператор «switch» или «case» (в зависимости от языка).Например, в PHP вы должны написать:

switch ($condition) {
  case 'a': do_something(); break;
  case 'b': do_something(); break;
  default: do_something();
}

Но точный синтаксис будет зависеть от языка, на котором вы пишете. В этой ситуации вы должны включить инструкции для других возможностей в раздел «по умолчанию», и это хорошая идея, чтобы включить что-то сюда, если возможно, чтобы условие было чем-то отличным от «a» или «b» (в противном случае вы получите ошибку!)

0 голосов
/ 05 марта 2011

Вторая версия будет оценивать каждое утверждение if независимо от результата предыдущих оценок.

Фактически он даже покажет неправильное поведение для того, чего вы хотите достичь, потому что всегда вводится последнее, если условие не c И не, если это не один из a, b или c.

Первая версия должна работать как положено.

0 голосов
/ 05 марта 2011

Фрагмент двух кодов различен.

В первом из них каждый else if будет проверяться тогда и только тогда, когда предыдущее условие было неверным.Например, если a было верно, остальные не будут проверяться вообще.

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

Так что мое последнее слово будет таким: это не вопрос «лучше или нет», поскольку оба кода делают разные вещи. Это зависит от того, что вы хотите сделать!

0 голосов
/ 05 марта 2011

В последнем примере вы всегда оцениваете все условия, в то время как первый только оценивает их, пока не найдет true.Поэтому первый фрагмент кода будет работать немного лучше.

Если вам не нравится так много вложенных условий, return / break метод после нахождения первого:

if(a)
  return do_something();
if(b)
  return do_something();
if(c)
  return do_something();
return do_something();

... если вы не преданный верующий в Церковь единого return.

...