Spec-Zone.ru › Elixir 1.16

Source case, cond и if

В этой главе мы изучим управляющие структуры case, cond, и if.

case

case позволяет нам сравнивать значение с множеством шаблонов, пока мы не найдём соответствующий:

iex> case {1, 2, 3} do
...>   {4, 5, 6} ->
...>     "This clause won't match"
...>   {1, x, 3} ->
...>     "This clause will match and bind x to 2 in this clause"
...>   _ ->
...>     "This clause would match any value"
...> end
"This clause will match and bind x to 2 in this clause"

Если вы хотите сопоставить шаблон с существующей переменной, вам необходимо использовать оператор ^:

iex> x = 1
1
iex> case 10 do
...>   ^x -> "Won't match"
...>   _ -> "Will match"
...> end
"Will match"

В пунктах также можно указывать дополнительные условия с помощью охранных условий:

iex> case {1, 2, 3} do
...>   {1, x, 3} when x > 0 ->
...>     "Will match"
...>   _ ->
...>     "Would match, if guard condition were not satisfied"
...> end
"Will match"

Первый пункт выше будет соответствовать только тогда, когда x положительно.

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

iex> hd(1)
** (ArgumentError) argument error
iex> case 1 do
...>   x when hd(x) -> "Won't match"
...>   x -> "Got #{x}"
...> end
"Got 1"

Если ни один из пунктов не соответствует, возникает ошибка:

iex> case :ok do
...>   :error -> "Won't match"
...> end
** (CaseClauseError) no case clause matching: :ok

В документации модуля Kernel перечислены все доступные охранные условия в боковой панели. Вы также можете обратиться к справочному руководству Шаблоны и охранные условия для получения подробной документации.

cond

case полезно, когда вам нужно сопоставить разные значения. Однако во многих случаях мы хотим проверить различные условия и найти первое, которое не оценивается как nil или false. В таких случаях можно использовать cond:

iex> cond do
...>   2 + 2 == 5 ->
...>     "This will not be true"
...>   2 * 2 == 3 ->
...>     "Nor this"
...>   1 + 1 == 2 ->
...>     "But this will"
...> end
"But this will"

Это эквивалентно пунктам else if во многих императивных языках — хотя используется реже в Elixir.

Если все условия возвращают nil или false, возникает ошибка (CondClauseError). По этой причине может потребоваться добавить конечное условие, равное true, которое всегда будет соответствовать:

iex> cond do
...>   2 + 2 == 5 ->
...>     "This is never true"
...>   2 * 2 == 3 ->
...>     "Nor this"
...>   true ->
...>     "This is always true (equivalent to else)"
...> end
"This is always true (equivalent to else)"

Наконец, обратите внимание, что cond рассматривает любое значение, кроме nil и false как истинное:

iex> cond do
...>   hd([1, 2, 3]) ->
...>     "1 is considered as true"
...> end
"1 is considered as true"

if/unless

Помимо case и cond, Elixir также предоставляет if/2 и unless/2, которые полезны, когда вам нужно проверить только одно условие:

iex> if true do
...>   "This works!"
...> end
"This works!"
iex> unless true do
...>   "This will never be seen"
...> end
nil

Если условие, заданное if/2, возвращает false или nil, тело, заданное между do-end, не выполняется, а вместо этого возвращается nil. Обратное происходит с unless/2.

Они также поддерживают else блоки:

iex> if nil do
...>   "This won't be seen"
...> else
...>   "This will"
...> end
"This will"

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

iex> x = 1
1
iex> if true do
...>   x = x + 1
...> end
2
iex> x
1

В таких случаях, если вы хотите изменить значение, вам необходимо вернуть значение из if:

iex> x = 1
1
iex> x = if true do
...>   x + 1
...> else
...>   x
...> end
2

if и unless являются макросами

Интересно, что if/2 и unless/2 реализованы как макросы в языке: они не являются специальными языковыми конструкциями, как в многих других языках. Вы можете проверить документацию и их исходный код для получения дополнительной информации.

Мы завершили введение в самые основные управляющие структуры потока в Elixir. Теперь давайте узнаем, где код и данные встречаются с анонимными функциями.

← Предыдущая страница Сопоставление с образцом
Следующая страница → Анонимные функции

Скачать версию ePub

Создано с помощью ExDoc (v0.32.2) для языка программирования Elixir

© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.16.3/case-cond-and-if.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API