I am reading Elixir's pattern matching and I am a little confused on =
operator being a match operator.
The website says
Elixir, the = operator is actually called the match operator.
And it gives this example:
iex> x = 1
1
iex> x
1
iex> 1 = x
1
iex> 2 = x
** (MatchError) no match of right hand side value: 1
For some reason, I still don't understand what 1 = x
is doing. It returns 1
if I put the value of the variable I had just assigned to the left of =
and throws error if the value is not the same. I can't really see how this is useful.
What does it mean for =
to be a match operator ? Is it similar to 1 == x
(if so, why doesn't it return true/false
)? When will I ever use match operator?
- What does it mean for = to be a match operator?
It means whether left can match the right, if their value are equal, they can match.
=
can also use as bind, which may confused you. Note that bind is not equal to assign.
a = 1
is binding value 1 to a. 1 = a
is check whether 1 matches a.
Variables as left operator are all binding, in this situation, bind can be confused with match in a =1
, so there is a syntax ^
call pin operator.
^a = 1
is check whether a matches 1.
- Is it similar to 1 == x (if so, why doesn't it return true/false)?
As mentioned in 1, it is not ==
. ==
is ==
in Elixir and will return true or false.
- When will I ever use match operator?
You will use it in function param match, map kv match, function return value match etc.
case song_id_info do
"" -> ""
{:ok, song_id} -> song_id
{:error, reason} -> IO.puts "error get_song_id #{reason}"
end
This one is to match song_id_info
with ""
, {:ok, song_id}
and {:error, reason}
. When song_id_info
not match one of them, error will be raised.
If you study deeper, you can know how match works perfectly at the end.
1 = x
is the contrived example that probably fooled you. In general, match operator assures that the RHO matches LHO, meaning LHO has nothing violating what RHO has. It's not about the exact match since LHO might in general a) assure that only the part of RHO is matched and b) might be more permissive than the equality check ( ==
).
In the case of 1
, well 1
is 1
, that's why the example looks contrived. On the other hand, =
for the match operator is the common syntax, covering all the cases. 1 === 1
in javascript also looks a bit weird, and one might ask “why would I ever need triple-equal,” seeing this example only.
On the other hand, match operator uses in:
def print(1), do: ...
def print(other), do: ...
when print(my_var)
is called somewhere in the code, the match operator is implicitly called on each clause, from top to bottom in the order of clauses declaration, to find the matched clause . That said, the following code:
defmodule M do
def print(1), do: "Neo"
def print(other), do: "toN Neo: #{other}"
end
my_var = 5
M.print(my_var)
#⇒ "toN Neo: 5"
is roughly equivalent to:
# ⇓ HERE match operator is used
if 1 = my_var do # this alone would raise MatchError
# but bear with me: ErlangVM
# takes care of that when finding
# a proper clause and it indeed
# uses match operator, not `==`
"Neo"
else
"toN Neo: #{other}"
end
case
matching case my_var do
1 -> "Neo"
other -> "noT Neo: #{other}"
end
the above is roughly the same as before.
The example below involves more complicated term than just an integer since my_new_var = my_var
would be called binding , although this is just a terminology muddle and we could safely call it “matching” as well without loss of the generality.
%{foo: my_var} = %{foo: 42}
here my_var
gets matched to 42
because LHO matches RHO in general and the key is the same.
The equality operator differs in two ways:
%{} == %{foo: 42}
fails, while %{} = %{foo: 42}
succeeds); %{foo: my_var} == %{foo: 42}
fails with “undefined function my_var/0”). The example of how match differs from equality operator in ruby (in ruby the role of match operator roughly plays triple-equal aka case-equal aka threequals):
/n/ === "One" #⇒ true
String === "One" #⇒ true
->(s) { s.length == 3 } === "One" #⇒ true
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.