Охранник (информатика)
Эта статья включает список общих ссылок , но в ней отсутствуют достаточные соответствующие встроенные цитаты . ( сентябрь 2010 г. ) |
В компьютерном программировании ограничитель — это логическое выражение , которое должно иметь значение true, если должно продолжаться выполнение программы в рассматриваемой ветви. Независимо от того, какой язык программирования используется, защитное предложение , защитный код или сторожевой оператор — это проверка предварительных условий целостности , используемых для предотвращения ошибок во время выполнения.
Использование
[ редактировать ]Типичным примером является проверка того, что ссылка, которая будет обработана, не является нулевой, что позволяет избежать сбоев нулевого указателя .
Другие варианты использования включают использование логического поля для идемпотентности (поэтому последующие вызовы являются nops ), как в шаблоне расположения .
public string Foo(string username)
{
if (username == null) {
throw new ArgumentNullException(nameof(username), "Username is null.");
}
// Rest of the method code follows here...
}
Более плоский код с меньшим количеством вложений
[ редактировать ]Защита обеспечивает ранний выход из подпрограммы и является широко используемым отклонением от структурного программирования , удаляя один уровень вложенности и приводя к более плоскому коду: [1] замена if guard { ... }
с if not guard: return; ...
.
Использование защитных предложений может быть методом рефакторинга для улучшения кода. В целом, меньшее количество вложений — это хорошо, поскольку это упрощает код и снижает когнитивную нагрузку.
Например, в Python :
# This function has no guard clause
def f_noguard(x):
if isinstance(x, int):
#code
#code
#code
return x + 1
else:
return None
# Equivalent function with a guard clause. Note that most of the code is less indented, which is good
def f_guard(x):
if not isinstance(x, int):
return None
#code
#code
#code
return x + 1
Другой пример, написанный на C :
// This function has no guard clause
int funcNoGuard(int x) {
if (x >= 0) {
//code
//code
//code
return x + 1;
} else {
return 0;
}
}
// Equivalent function with a guard clause
int funcGuard(int x) {
if (x < 0) {
return 0;
}
//code
//code
//code
return x + 1;
}
Терминология
[ редактировать ]Этот термин используется с определенным значением в APL , Haskell , Clean , Erlang , occam , Promela , OCaml , Swift , [2] Python начиная с версии 3.10 и Scala . языки программирования [ нужна ссылка ] В системе Mathematica меры защиты называются ограничениями . Охранники являются фундаментальной концепцией в Guarded Command Language , языке формальных методов . Охранники можно использовать для дополнения сопоставления с образцом возможностью пропуска шаблона, даже если структура совпадает. Булевы выражения в условных операторах обычно также соответствуют этому определению защиты, хотя они и называются условиями .
Математика
[ редактировать ]В следующем примере Haskell защитные элементы встречаются между каждой парой символов "|". и "=":
f x
| x > 0 = 1
| otherwise = 0
Это похоже на соответствующее математическое обозначение:
В этом случае защита находится в предложениях «если» и «иначе».
Несколько охранников
[ редактировать ]Если имеется несколько параллельных охранников, они обычно опробуются в порядке сверху вниз, и выбирается ветвь, прошедшая первым. Охранники в списке дел обычно параллельны.
Однако в понимании списков Haskell меры защиты расположены последовательно, и если какой-либо из них дает сбой, элемент списка не создается. Это было бы то же самое, что объединение отдельных защитных элементов с помощью логического И , за исключением того, что среди защитных элементов могут быть и другие элементы понимания списка.
Эволюция
[ редактировать ]Простое условное выражение, уже присутствующее в CPL в 1963 году, имеет защиту для первого подвыражения и еще одно подвыражение, которое можно использовать на случай, если первое невозможно использовать. Некоторые распространенные способы написать это:
(x>0) -> 1/x; 0 x>0 ? 1/x : 0
Если второе подвыражение может быть еще одним простым условным выражением, мы можем предоставить больше альтернатив, которые можно попробовать перед последним провалом :
(x>0) -> 1/x; (x<0) -> -1/x; 0
В 1966 году ISWIM имел форму условного выражения без обязательного пропускающего падежа, что отделяло защиту от концепции выбора «или-или». В случае с ISWIM, если ни одна из альтернатив не могла быть использована, значение должно было быть неопределенным , которое никогда не могло быть преобразовано в значение.
KRC , «миниатюрная версия» [3] SASL (1976) был одним из первых языков программирования , в котором использовался термин «защита». Определения его функций могли состоять из нескольких предложений, и то, которое нужно применить, выбиралось на основе защитных мер, следующих за каждым предложением:
fac n = 1, n = 0
= n * fac (n-1), n > 0
Использование защитных предложений и термина «защитное предложение» восходит, по крайней мере, к практике Smalltalk в 1990-х годах, как это кодифицировано Кентом Беком . [1]
В 1996 году Dyalog APL принял альтернативный чисто функциональный стиль, в котором единственной структурой управления является защита. [4] В этом примере в APL вычисляется четность входного числа:
parity←{
2∣⍵ : 'odd'
'even'
}
Узорная охрана
[ редактировать ]В дополнение к защите, прикрепленной к шаблону, защита по образцу может относиться к использованию сопоставления с образцом в контексте защиты. По сути, совпадение с шаблоном считается пройденным. Это значение было введено в предложении для Haskell Саймоном Пейтоном Джонсом под названием «Новый взгляд на охранников» в апреле 1997 года и использовалось при реализации этого предложения. Эта функция предоставляет возможность использовать шаблоны в защите шаблона.
Пример на расширенном Haskell:
clunky env var1 var2
| Just val1 <- lookup env var1
, Just val2 <- lookup env var2
= val1 + val2
-- ...other equations for clunky...
Это будет звучать так: «Неуклюже для среды и двух переменных, в случае, если поиск переменных из среды дает значения , является суммой значений. ...» Как и в случае с пониманием списков , защитные меры расположены последовательно, и если любой из них терпит неудачу, ветка не берется.
См. также
[ редактировать ]- Утверждение
- Guarded Command Language — язык программирования, основанный на недетерминированных условных выражениях.
- Защищенная подвеска
- Кронштейн Айверсона
- Логическое условное
- Узел Sentinel — объект, обозначающий конец структуры данных.
- Оператор переключения
Ссылки
[ редактировать ]- ^ Jump up to: а б Бек, Кент (1997). «Охранная статья». Шаблоны передового опыта Smalltalk, . стр. 178–179.
- ^ Кук, Нейт. «охранять и откладывать» . НШипстер . Проверено 26 февраля 2016 г.
- ^ Тернер, Д.А. «Некоторые истории языков функционального программирования» (PDF) .
- ^ Скоулз, Джон. «Прямые функции в Dyalog APL» (PDF) .
Внешние ссылки
[ редактировать ]- Guard в бесплатном онлайн-словаре по вычислительной технике — FOLDOC , Денис Хоу (редактор).
- Оговорка о защите , WikiWikiWeb
- Отчет Haskell 98 , глава 3. Выражения .
- Книга Mathematica, раздел 2.3.5. Наложение ограничений на шаблоны
- Руководство пользователя системы компиляции Haskell Glorious Glasgow , версия 6.4, раздел 7.3.2. Узорные охранники