2009-11-16 2 views
5

Вопросы, относящиеся: Benefits of using short-circuit evaluation, Why would a language NOT use Short-circuit evaluation?, Can someone explain this line of code please? (Logic & Assignment operators)Зачем использовать код короткого замыкания?

Есть вопросы о преимуществах языка с использованием кода короткого замыкания, но мне интересно, какие преимущества для программиста? Это просто, что он может сделать код немного более кратким? Или есть причины для повышения производительности?

Я не спрашиваю о ситуациях, когда необходимо оценить так или иначе два объекта, например:

if($user->auth() AND $model->valid()){ 
    $model->save(); 
} 

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

Это также имеет (для меня) очевидную цель:

if(is_string($userid) AND strlen($userid) > 10){ 
    //do something 
}; 

Потому что это было бы неразумно называть strlen() со значением нестроковой.

Что мне интересно, так это использование кода короткого замыкания, когда оно не влияет на другие заявления. Например, на странице Zend указательным приложений по умолчанию:

defined('APPLICATION_PATH') 
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 

Это могло бы быть:

if(!defined('APPLICATION_PATH')){ 
    define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 
} 

Или даже как одно утверждение:

if(!defined('APPLICATION_PATH')) 
    define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 

Так почему использовать кратко- код цепи? Только для коэффициента «прохлады» использования логических операторов вместо структур управления? Чтобы консолидировать вложенные операторы if? Потому что это быстрее?

+0

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

+0

@David Это верно и для языков сценариев? –

+0

@TimLytle в интерпретируемых языках вы можете иметь разные типы поведения из-за различного анализа и интерпретации. Компиляторы извлекают выгоду из того, что нужно сделать до того, как у кода появится возможность запуска. –

ответ

4

Для программистов, благо менее подробного синтаксиса над другой, более подробный синтаксис может быть:

  • меньше типа, следовательно, более высокая эффективность кодирования
  • меньше читать, поэтому лучше ремонтопригодность.

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

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

  • анонимные внутренние классы в Java вместо передачи указателя на функцию (путь больше строк кода).
  • в Ruby, оператор || =, для оценки выражения и назначения ему, если он оценивает значение false или имеет значение null. Конечно, вы можете достичь того же уровня тремя строками кода, но почему?
  • и многое другое ...
0

Что делать, если у вас была дорогая функция вызова (производительность), которая вернула логическое значение с правой стороны, которое вы хотели бы вызвать только в том случае, если другое условие было истинным (или ложным)? В этом случае короткое замыкание экономит много циклов процессора. Это делает код более кратким из-за меньшего количества вложенных операторов if. Итак, по всем причинам, перечисленным в конце вашего вопроса.

+0

Да, это один из примеров, которые я цитирую как имеющие очевидную причину. См. Пример $ model-> valid(). –

+0

Точно. Все причины, которые вы приводите, являются очень вескими основаниями для оценки короткого замыкания. – Poindexter

4

Используйте его, чтобы запутать людей!

+0

Или, возможно, держать (легко запутавшийся) рифф-рейфф от общения с кодом. – NVRAM

4

Я не знаю PHP, и я никогда не видел короткое замыкание используется за пределами, если или когда условия в семье C языков, но в Perl это очень идиоматических сказать:

open my $filehandle, '<', 'filename' or die "Couldn't open file: $!"; 

One Преимущество наличия всего в одном утверждении - объявление переменной. В противном случае вам следует сказать:

my $filehandle; 
unless (open $filehandle, '<', 'filename') { 
    die "Couldn't open file: $!"; 
} 

В этом случае трудно претендовать на второе место. И это было бы слово еще на языке, который не имеет unless

+2

Меньше материала для ввода текста делает программистов счастливыми. – nos

2

Я думаю, что ваш пример для коэффициента прохлады. Нет причин писать такой код.

EDIT: У меня нет проблем с этим по идиоматическим причинам. Если все, кто использует язык, используют оценку короткого замыкания, чтобы сделать объекты, подобные утверждениям, которые все понимают, тогда вам тоже нужно.Однако мой опыт заключается в том, что такой код редко записывается на языках C-семейства; правильная форма - просто использовать оператор «если» как нормальный, который отделяет условный (который, предположительно, не имеет побочных эффектов) от вызова функции, что условные элементы управления (которые предположительно имеют много побочных эффектов).

1

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

0

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

А и В и с

Есть два члена в этой формуле вычисляется слева направо.

Если a и b оценивается как ЛОЖЬ, то следующее выражение AND c может быть FALSE AND TRUE или FALSE AND FALSE. Оба оценивают значение FALSE независимо от значения c. Поэтому компилятор не содержит AND c в скомпилированном формате, поэтому короткое замыкание кода.

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

2

операторы Короткие замыкания могут быть полезны в двух важных обстоятельствах, которые еще не были упомянуты:

Case 1. Предположим, у вас есть указатель, который может быть или не быть NULL, и вы хотели проверить, что это не было NULL, и что на него указывалось не 0. Тем не менее, вы должны не разыскивать указатель, если он NULL.Без операторов короткого замыкания, вы должны сделать это:

if (a != NULL) { 
    if (*a != 0) { 
    ⋮ 
    } 
} 

Однако операторы короткого замыкания позволяют записать это более компактно:

if (a != NULL && *a != 0) { 
    ⋮ 
} 

в определенном знании, что *a будет не будет оценен, если a - NULL.

Дело 2. Если вы хотите установить переменный не-ложное значение, возвращенное из одного ряда функций, вы можете просто сделать:

my $file = $user_filename || 
      find_file_in_user_path() || 
      find_file_in_system_path() || 
      $default_filename; 

Это устанавливает значение $file в $user_filename, если он присутствует, или результат find_file_in_user_path(), если это правда, или ... так далее. Это видно, возможно, чаще в Perl, чем C, но я видел его в C.

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

+0

Это «консолидировать вложенные операторы if», которые я не мог вспомнить в прошлом или придумать пример кода. –

0

Подумайте об этом так, если у вас есть такое заявление

if(A AND B) 

шансы, если А возвращает FALSE вы только когда-либо хотите оценить B в редких специальных случаях. По этой причине НЕиспользование короткой оценки ciruit запутывает.

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

Смежные вопросы