Перейти до основного вмісту

Зіставлення по зразку в Elixir

Зіставлення по зразку (pattern matching) — це одна з найпотужніших можливостей мови Elixir. Це не просто присвоєння значень змінним, а механізм для деструктуризації даних та перевірки їхньої структури.

Основи зіставлення

В Elixir оператор = — це не оператор присвоєння, а оператор зіставлення. Він намагається зробити ліву частину рівною правій.

# Проста змінна
x = 1
# x тепер дорівнює 1

# Зіставлення зі значенням
1 = x
# Це працює, тому що x = 1

# Помилка зіставлення
2 = x
# ** (MatchError) no match of right hand side value: 1

Зіставлення зі списками

Зіставлення дозволяє витягувати елементи зі списків:

# Зіставлення всього списку
[a, b, c] = [1, 2, 3]
# a = 1, b = 2, c = 3

# Виділення голови та хвоста
[head | tail] = [1, 2, 3, 4]
# head = 1, tail = [2, 3, 4]

# Ігнорування елементів
[_, second, _] = [10, 20, 30]
# second = 20

Зіставлення з кортежами

Кортежі часто використовуються для зіставлення, особливо для обробки результатів функцій:

# Зіставлення з кортежем
{status, result} = {:ok, "Success"}
# status = :ok, result = "Success"

# Обробка помилок
case File.read("file.txt") do
  {:ok, content} -> 
    IO.puts("Вміст: #{content}")
  {:error, reason} -> 
    IO.puts("Помилка: #{reason}")
end

Зіставлення з картами (maps)

Карти дозволяють витягувати значення за ключами:

# Витягування значень
%{name: name, age: age} = %{name: "Іван", age: 30, city: "Київ"}
# name = "Іван", age = 30

# Часткове зіставлення
%{name: name} = %{name: "Марія", age: 25}
# name = "Марія" (age ігнорується)

# Зіставлення з конкретним значенням
%{status: :active, user: user} = %{status: :active, user: "admin"}
# Спрацює тільки якщо status = :active

Пін-оператор (^)

Використовується для зіставлення з існуючим значенням змінної замість створення нової прив'язки:

x = 1

# Без пін-оператора (перезапис)
x = 2
# x тепер дорівнює 2

# З пін-оператором (зіставлення)
x = 1
^x = 1  # OK
^x = 2  # MatchError

# Практичне застосування
[^x, y] = [1, 2]  # OK, y = 2
[^x, y] = [2, 3]  # MatchError

Зіставлення у функціях

Зіставлення по зразку особливо корисне при визначенні функцій з різними варіантами вхідних даних:

defmodule Calculator do
  # Зіставлення за значенням
  def operate(:add, a, b), do: a + b
  def operate(:subtract, a, b), do: a - b
  def operate(:multiply, a, b), do: a * b
  
  # Зіставлення зі структурами
  def process_user(%{name: name, admin: true}) do
    "Адміністратор: #{name}"
  end
  
  def process_user(%{name: name}) do
    "Користувач: #{name}"
  end
  
  # Рекурсія зі списками
  def sum([]), do: 0
  def sum([head | tail]), do: head + sum(tail)
end

Охоронці (Guards)

Охоронці дозволяють додавати додаткові умови до зіставлення:

defmodule Numbers do
  def check(x) when x > 0, do: "Позитивне"
  def check(x) when x < 0, do: "Негативне"
  def check(0), do: "Нуль"
  
  def adult?(age) when age >= 18, do: true
  def adult?(_), do: false
  
  # Комбіновані охоронці
  def classify(x) when is_integer(x) and x > 0, do: "Натуральне"
  def classify(x) when is_float(x), do: "Дробове"
end

Практичні приклади

Приклади реального використання зіставлення:

# Обробка HTTP-відповідей
case HTTPoison.get(url) do
  {:ok, %{status_code: 200, body: body}} ->
    {:ok, body}
  {:ok, %{status_code: 404}} ->
    {:error, :not_found}
  {:error, reason} ->
    {:error, reason}
end

# Парсинг команд
def handle_command(["create", name]) do
  create_item(name)
end

def handle_command(["delete", id]) when is_binary(id) do
  delete_item(id)
end

def handle_command(_) do
  {:error, "Невідома команда"}
end

Переваги зіставлення по зразку

  • Читабельність: код стає більш декларативним і зрозумілим
  • Безпека: компілятор попереджає про неповні зіставлення
  • Деструктуризація: легко витягувати дані зі складних структур
  • Елегантність: замінює багато if/else конструкцій
  • Функціональний стиль: природно поєднується з рекурсією та незмінністю

Зіставлення по зразку — це фундаментальна концепція Elixir, яка робить код більш виразним та надійним.

Коментарі

Популярні публікації

Колекції в Elixir

Списки Що таке список у Elixir У Elixir список — це впорядкована колекція елементів, реалізована як однозв’язний список . Це означає, що кожен елемент (вузол) зберігає посилання на наступний, але не на попередній. Така структура дозволяє швидко додавати елементи на початок списку, але повільно доступати до довільного елементу. У Java подібну структуру представляє LinkedList — частина Java Collections Framework. Вона реалізована як двозв’язний список, що забезпечує зручне додавання/видалення елементів з початку або кінця списку. Створення списків У Elixir список створюється за допомогою квадратних дужок: list = [1, 2, 3, 4] Додавання елементів У Elixir новий елемент можна додати тільки на початок списку за допомогою оператора | : # Elixir list = [2, 3, 4] new_list = [1 | list] # [1, 2, 3, 4] Доступ до елементів У Elixir немає прямого доступу до елементів за індексом, але це можна зробити через Enum.at : Enum.at([10, 20, 30], 1) # 20 Ітерація по списку У Elixir ...

Інструменти для роботи з Node.js

Що таке npm? npm (Node Package Manager) — це офіційний пакетний менеджер для Node.js . Він дозволяє: Встановлювати сторонні бібліотеки та фреймворки Керувати залежностями проєкту Запускати скрипти (команди) через package.json Приклад ініціалізації проєкту з npm npm init -y Файл package.json (скорочений приклад) { "name": "my-project", "version": "1.0.0", "scripts": { "start": "ts-node src/index.ts", "build": "tsc" }, "dependencies": { "express": "^4.18.0" }, "devDependencies": { "typescript": "^5.0.0", "ts-node": "^10.0.0" } } Що таке tsconfig.json? tsconfig.json — це файл конфігурації для компілятора TypeScript, який визначає, як слід компілювати код. Приклад файлу tsconfig.json { "compilerOptions": { "target": "ES2020...

Атоми в мові програмування Elixir

Атоми в Elixir Атоми є фундаментальною концепцією в Elixir , що відіграє ключову роль у створенні надійних та масштабованих систем. В Elixir це специфічний тип даних, який є константою , незмінною , ідентифікованою за своїм ім'ям . Отже, атом в Elixir — це іменована константа, що представляє себе. Уявіть, що ви даєте унікальне ім'я певній речі, і це ім'я завжди посилається саме на цю річ, і ніколи на щось інше. Наприклад, атом :ok завжди буде означати саме успішне завершення операції, а не якесь інше значення. Технічно, атоми є похідними від чисел . Кожен унікальний атом зберігається у таблиці атомів, і йому присвоюється унікальний цілочисельний ідентифікатор. Це робить їх надзвичайно ефективними для порівняння: замість порівняння рядків (що є повільною операцією), Elixir порівнює цілочисельні ідентифікатори. Переваги та особливості використання атомів Переваги атомів: Ефективність. Завдяки своєму числовому представленню, порівняння атомів є дуже швидким. Це осо...

Встановлення PostgreSQL на Ubuntu-сервер

Встановлення Оновлюємо пакети та встановлюємо PostgreSQL: sudo apt update sudo apt install -y postgresql postgresql-contrib Перевіряємо статус сервісу: sudo systemctl status postgresql Якщо PostgreSQL не запущений, запустимо його: sudo systemctl start postgresql sudo systemctl enable postgresql Налаштування безпеки Зміна пароля: sudo -u postgres psql У консолі PostgreSQL: ALTER USER postgres PASSWORD 'міцний_пароль'; \q \q - вихід з консолі. Список основних команд для роботи з PostgreSQL можна переглянути за посиланням. За замовчуванням PostgreSQL слухає localhost (127.0.0.1). Щоб дозволити доступ із зовнішніх машин, редагуємо конфігурацію: sudo nano /etc/postgresql/17/main/postgresql.conf (замість 17 вкажи версію PostgreSQL, яку встановлено) Шукаємо рядок: #listen_addresses = 'localhost' та замінюємо на listen_addresses = '*' Зберігаємо (Ctrl + X, Y, Enter). Тепер редагуємо pg_hba.conf: sudo nano /etc/postgresql/17/main/pg_hba.conf...

Основи Node.js

Що таке Node.js? Node.js — це середовище виконання JavaScript поза браузером, побудоване на рушії Google V8 . Воно дозволяє запускати JavaScript на сервері, створюючи серверні застосунки з високою продуктивністю. Основні характеристики: Однопотокова модель з неблокуючим I/O Асинхронне виконання за допомогою event loop Висока продуктивність у роботі з мережевими запитами npm — найбільший реєстр пакетів Що таке event loop? Event loop — це механізм в Node.js, який дозволяє неблокуючим асинхронним операціям виконуватись у середовищі з єдиним потоком. Він постійно перевіряє наявність подій у черзі та викликає відповідні колбеки. Як працює однопоточність у Node.js? Node.js використовує один потік (main thread) для обробки JavaScript-коду. Операції, які займають час (мережеві запити, читання з файлової системи), делегуються до системних API або thread pool, і після завершення результат повертається у основний потік через event loop. Приклад: асинхронна о...