iex> handle_result =fn...> {:ok, result} ->IO.puts"Handling result..."...> {:ok,_} ->IO.puts"This would be never run as previous will be matched beforehand."...> {:error} ->IO.puts"An error has occurred!"...>endiex> some_result =1iex>handle_result.({:ok, some_result})Handling result...iex>handle_result.({:error})An error has occurred!
# 传入一个不包含相应键值的字典后,会产生如下错误...>Greeter1.hello(%{age: "95", favorite_color: "Taupe"})** (FunctionClauseError) no function clause matching inGreeter3.hello/1The following arguments were given to Greeter3.hello/1:# 1 %{age: "95", favorite_color: "Taupe"} iex:12:Greeter3.hello/1
当它在传入的字典中找到相应的键 :name 时,这个匹配就成立了。匹配成功的结果就是,右边字典中 :name 键对应的值(在 fred 字典中),就赋予到左边的变量(person_name)上。
那么,如果我们除了希望把 Fred 的姓名赋值到 person_name 外,我们还希望保留整个人物信息的字典,要怎么做呢?比如说我们希望在和他打招呼后运行 IO.inspect(fred)。上面的做法,因为我们只是模式匹配了 :name 这个键值,也因此只是把它的值赋予了一个变量,函数本身并不知道 Fred 其它的信息。
# 传入整个人的资料...>Greeter2.hello(fred)"Hello, Fred"%{age: "95", favorite_color: "Taupe", name: "Fred"}# 传入只是包含了 name 键值的字典...>Greeter4.hello(%{name: "Fred"})"Hello, Fred"%{name: "Fred"}# 传入不包含 name 键值的字典...>Greeter4.hello(%{age: "95", favorite_color: "Taupe"})** (FunctionClauseError) no function clause matching inGreeter2.hello/1The following arguments were given to Greeter2.hello/1:# 1 %{age: "95", favorite_color: "Taupe"} iex:15:Greeter2.hello/1
所以,Elixir 的模式匹配能按传入的数据,独立匹配每一个参数。
如果我们改变 %{name: person_name} 和 person 的顺序,结果还是一样的。比如:
defmoduleGreeterdodefhello(names, language_code \\"en") whenis_list(names) do names|>Enum.join(", ")|>hello(language_code)enddefhello(name, language_code \\"en") whenis_binary(name) dophrase(language_code) <> nameenddefpphrase("en"), do: "Hello, "defpphrase("es"), do: "Hola, "end** (CompileError) iex:31: definitions with multiple clauses and default values require a header.Instead of:deffoo(:first_clause, b \\ :default) do...enddeffoo(:second_clause, b) do...endone should write:deffoo(a, b \\ :default)deffoo(:first_clause, b) do...enddeffoo(:second_clause, b) do...enddefhello/2 has multiple clauses and defines defaults in one or more clauses iex:31: (module)