x = 1
IO.inspect(x)
1 = x
IO.puts("1 = x matched")
1
1 = x matched
= is the match operator. The left side is a
pattern; Elixir makes it match the right side,
binding variables along the way.
x = 1
IO.inspect(x)
1 = x
IO.puts("1 = x matched")
1
1 = x matched
A failed match raises MatchError.
try do
2 = x
rescue
e in MatchError -> IO.puts(Exception.message(e))
end
no match of right hand side value:
1
Patterns destructure tuples, lists and maps.
{:ok, result} = {:ok, 42}
[first, second | rest] = [1, 2, 3, 4]
%{name: name} = %{name: "Ada", age: 36}
IO.inspect({result, first, second, rest, name})
{42, 1, 2, [3, 4], "Ada"}
_ matches anything and binds nothing. Prefixing a
variable with _ documents what you ignore.
{_, _status, _} = {:http, 200, "OK"}
{:ok, _value} = {:ok, :ignored}
Variables can be rebound. To match against a
variable's current value instead, use the pin ^.
x = 2
IO.inspect(x)
expected = :ok
case {:ok, "done"} do
{^expected, msg} -> IO.puts("pinned match: #{msg}")
end
try do
^x = 3
rescue
e in MatchError -> IO.puts(Exception.message(e))
end
2
pinned match: done
no match of right hand side value:
3
The same variable twice in one pattern must match the same value.
{a, a} = {5, 5}
IO.inspect(a)
case {1, 2} do
{same, same} -> IO.puts("equal")
{_, _} -> IO.puts("different")
end
5
different
Matching works in function heads, case, with,
and comprehensions. It's the main way Elixir code
makes decisions.
handle = fn
{:ok, value} -> "got #{value}"
{:error, reason} -> "failed: #{reason}"
end
IO.puts(handle.({:ok, 1}))
IO.puts(handle.({:error, :timeout}))
got 1
failed: timeout
Pitfall:
=is not assignment.{:ok, data} = File.read(path)crashes on{:error, :enoent}. That's fine when failure is a bug, but usecaseorwithwhen failure is expected.
Pitfall: inside
case, a bare variable in a pattern rebinds, it doesn't compare. Writinguser_id -> ...matches anything. Use^user_id.