diff options
author | Ev Bogdanov <evbogdanov.com@gmail.com> | 2017-08-18 22:58:44 +0300 |
---|---|---|
committer | Ev Bogdanov <evbogdanov.com@gmail.com> | 2017-08-18 22:58:44 +0300 |
commit | e3f904d911e661fc74965be50bbfecd9f0b07d95 (patch) | |
tree | 8cb892343a3328aeb498af6a1fba399bcd7d9098 | |
parent | 81256bc904ee9f5c95b7e4c6f643236497efc8f8 (diff) |
[elixir/ru] Modules and Functions
-rw-r--r-- | ru-ru/elixir-ru.html.markdown | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/ru-ru/elixir-ru.html.markdown b/ru-ru/elixir-ru.html.markdown index 64150142..8342c1e5 100644 --- a/ru-ru/elixir-ru.html.markdown +++ b/ru-ru/elixir-ru.html.markdown @@ -238,4 +238,111 @@ end #=> Я выполнюсь всегда # "Поймана ошибка с сообщением hello." +## --------------------------- +## -- Модули и функции +## --------------------------- + +# Анонимные функции (обратите внимание на точку при вызове функции) +square = fn(x) -> x * x end +square.(5) #=> 25 + +# Анонимные функции принимают клозы и гарды. +# +# Клозы (от англ. clause) — варианты исполнения функции. +# +# Гарды (от англ. guard) — охранные выражения, уточняющие сопоставление с +# образцом в функциях. Гарды следуют после ключевого слова `when`. +f = fn + x, y when x > 0 -> x + y + x, y -> x * y +end + +f.(1, 3) #=> 4 +f.(-1, 3) #=> -3 + +# В Elixir много встроенных функций. +# Они доступны в текущей области видимости. +is_number(10) #=> true +is_list("hello") #=> false +elem({1,2,3}, 0) #=> 1 + +# Вы можете объединить несколько функций в модуль. Внутри модуля используйте `def`, +# чтобы определить свои функции. +defmodule Math do + def sum(a, b) do + a + b + end + + def square(x) do + x * x + end +end + +Math.sum(1, 2) #=> 3 +Math.square(3) #=> 9 + +# Чтобы скомпилировать модуль Math, сохраните его в файле `math.ex` +# и наберите в терминале: `elixirc math.ex` + +defmodule PrivateMath do + # Публичные функции начинаются с `def` и доступны из других модулей. + def sum(a, b) do + do_sum(a, b) + end + + # Приватные функции начинаются с `defp` и доступны только внутри своего модуля. + defp do_sum(a, b) do + a + b + end +end + +PrivateMath.sum(1, 2) #=> 3 +PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError) + +# Функции внутри модуля тоже принимают клозы и гарды +defmodule Geometry do + def area({:rectangle, w, h}) do + w * h + end + + def area({:circle, r}) when is_number(r) do + 3.14 * r * r + end +end + +Geometry.area({:rectangle, 2, 3}) #=> 6 +Geometry.area({:circle, 3}) #=> 28.25999999999999801048 +Geometry.area({:circle, "not_a_number"}) #=> ** (FunctionClauseError) + +# Из-за неизменяемых переменных в Elixir важную роль играет рекурсия +defmodule Recursion do + def sum_list([head | tail], acc) do + sum_list(tail, acc + head) + end + + def sum_list([], acc) do + acc + end +end + +Recursion.sum_list([1,2,3], 0) #=> 6 + +# Модули в Elixir поддерживают атрибуты. +# Атрибуты бывают как встроенные, так и ваши собственные. +defmodule MyMod do + @moduledoc """ + Это встроенный атрибут + """ + + @my_data 100 # А это ваш атрибут + IO.inspect(@my_data) #=> 100 +end + +# Одна из фишек языка — оператор `|>` +# Он передаёт выражение слева в качестве первого аргумента функции справа: +Range.new(1,10) +|> Enum.map(fn x -> x * x end) +|> Enum.filter(fn x -> rem(x, 2) == 0 end) +#=> [4, 16, 36, 64, 100] + ``` |