Pattern Matching

Elixir has first-class pattern matching support.

Control Flow

case {:ok, 1} do
  {:ok, value} -> value
  :error -> 0
end

In Rust:

#![allow(unused)]
fn main() {
    println!("{}", match Some(1) {
        Some(value) => value,
        None => 0
    });
}

Function Parameters

defmodule Greeter do
  def greet({:ok, name}), do: "Hello, #{name}"
  def greet(:error), do: "Error occurred"
end

Greeter.greet({:ok, "Alice"})
#![allow(unused)]
fn main() {
    enum Result<T, E> {
        Ok(T),
        Err(E),
    }
    
    fn greet(result: Result<&str, &str>) -> String {
        match result {
            Result::Ok(name) => format!("Hello, {}", name),
            Result::Err(_) => "Error occurred".to_string(),
        }
    }
    
    println!("{}", greet(Result::Ok("Alice")));
}

Guards

defmodule Number do
  def sign(n) when n > 0, do: :positive
  def sign(n) when n < 0, do: :negative
  def sign(0), do: :zero
end
#![allow(unused)]
fn main() {
    fn sign(n: i32) -> &'static str {
        match n {
            x if x > 0 => "positive",
            x if x < 0 => "negative",
            _ => "zero",
        }
    }
    println!("{}", sign(-1));
}

Wildcards

case value do
  {:ok, v} -> IO.puts("Got #{v}")
  _ -> IO.puts("Unknown")
end
match value {
    Some(v) => println!("Got {}", v),
    _ => println!("Unknown"),
}

It is worth mentioning that Rust has very useful compile-time exhaustiveness check, which is based on type system.