if — оператор для ветвления программы, то есть выполнения некоторых действий в зависимости от условия, одного или нескольких.
В общем виде конструкция if выглядит так:
if
Гарда1 -> Тело1;
Гарда2 -> Тело2;
...
end
Гарды (условия) выполняются последовательно: Гарда1, потом Гарда2… Как только гарда срабатывает, выполняется тело, связанное с ней. После этого происходит выход из оператора if ... end
с возвращением некоторого значения.
1> X = 10.
10
2> if
X > 0 -> big;
X > 5 -> very_big
end.
big
Как мы видим, сработала только первая гарда и запустила тело, состоящее из одного только выражения-атома big
. Этот атом и был возвращён из оператора if ... end
.
Каждая гарда возвращает true или false. Поэтому если мы желаем в конце конструкции вставить тело, которое отработает все прочие случаи, не предусмотренные предыдущими гардами, просто добавляем в конце гарду true. С ней в любом случае что-нибудь да произойдёт.
if
Гарда1 -> Тело1;
Гарда2 -> Тело2;
...
true -> ТелоN
end
Это форма оператора if ... end
, пожалуй, и является канонической. Дело в том, что если во время исполнения ни одна гарда не подойдёт, это вызовет исключение.
3> Y = -5.
-5
4> if
Y > 0 -> big;
Y > 5 -> very_big
end.
** exception error: no true branch found when evaluating
an if expression
Ветка Истины, говорит Эрланг, не найдена.
Тем не менее каждый раз, когда мы добавляем true -> ...
, лучше задать вопрос, точно ли я этого хочу. Не будет ли так, что ветка с true маскирует некоторую фундаментальную ошибку? Иногда бывает полезным дать программе в целом или отдельному актору упасть, нежели потом пытаться долго найти скрытую ошибку.
Оператор if похож на оператор case. Сложно сказать, кто из них более универсален. С одной стороны, if более гибок в том, что в условиях не ограничивается лишь одной переменной. С другой стороны, у case есть сравнение переменной с паттерном, и это в ряде случаев очень эффективно. Для ветвления можно также использовать функции и фунтермы, имеющие по несколько кляуз.
© Алексей Карманов, 2024.