# 函數

## 匿名 (Anonymous) 函數

``````iex> sum = fn (a, b) -> a + b end
iex> sum.(2, 3)
5
``````

### & 簡寫符號

``````iex> sum = &(&1 + &2)
iex> sum.(2, 3)
5
``````

## 模式比對

Elixir 使用模式比對來識別相配的第一組參數，接著執行相對應的函數：

``````iex> handle_result = fn
...>   {:ok, result} -> IO.puts "Handling result..."
...>   {:error} -> IO.puts "An error has occurred!"
...> end

iex> some_result = 1
iex> handle_result.({:ok, some_result})
Handling result...

iex> handle_result.({:error})
An error has occurred!
``````

## 命名 (Named) 函數

``````defmodule Greeter do
def hello(name) do
"Hello, " <> name
end
end

iex> Greeter.hello("Sean")
"Hello, Sean"
``````

``````defmodule Greeter do
def hello(name), do: "Hello, " <> name
end
``````

``````defmodule Length do
def of([]), do: 0
def of([_ | tail]), do: 1 + of(tail)
end

iex> Length.of []
0
iex> Length.of [1, 2, 3]
3
``````

### 函數命名和引數數目 (Arity)

``````defmodule Greeter2 do
def hello(), do: "Hello, anonymous person!"   # hello/0
def hello(name), do: "Hello, " <> name        # hello/1
def hello(name1, name2), do: "Hello, #{name1} and #{name2}"
# hello/2
end

iex> Greeter2.hello()
"Hello, anonymous person!"
iex> Greeter2.hello("Fred")
"Hello, Fred"
iex> Greeter2.hello("Fred", "Jane")
"Hello, Fred and Jane"
``````

### 私有 (Private) 函數

``````defmodule Greeter do
def hello(name), do: phrase <> name
defp phrase, do: "Hello, "
end

iex> Greeter.hello("Sean")
"Hello, Sean"

iex> Greeter.phrase
** (UndefinedFunctionError) function Greeter.phrase/0 is undefined or private
Greeter.phrase()
``````

### 監視 (Guards)

``````defmodule Greeter do
def hello(names) when is_list(names) do
names
|> Enum.join(", ")
|> hello
end

def hello(name) when is_binary(name) do
phrase() <> name
end

defp phrase, do: "Hello, "
end

iex> Greeter.hello ["Sean", "Steve"]
"Hello, Sean, Steve"
``````

### 預設 (Default) 引數值

``````defmodule Greeter do
def hello(name, language_code \\ "en") do
phrase(language_code) <> name
end

defp phrase("en"), do: "Hello, "
defp phrase("es"), do: "Hola, "
end

iex> Greeter.hello("Sean", "en")
"Hello, Sean"

iex> Greeter.hello("Sean")
"Hello, Sean"

iex> Greeter.hello("Sean", "es")
"Hola, Sean"
``````

``````defmodule Greeter do
def hello(names, language_code \\ "en") when is_list(names) do
names
|> Enum.join(", ")
|> hello(language_code)
end

def hello(name, language_code \\ "en") when is_binary(name) do
phrase(language_code) <> name
end

defp phrase("en"), do: "Hello, "
defp phrase("es"), do: "Hola, "
end

** (CompileError) iex:31: definitions with multiple clauses and default values require a header. Instead of:

def foo(:first_clause, b \\ :default) do ... end
def foo(:second_clause, b) do ... end

one should write:

def foo(a, b \\ :default)
def foo(:first_clause, b) do ... end
def foo(:second_clause, b) do ... end

def hello/2 has multiple clauses and defines defaults in one or more clauses
iex:31: (module)
``````

``````defmodule Greeter do
def hello(names, language_code \\ "en")
def hello(names, language_code) when is_list(names) do
names
|> Enum.join(", ")
|> hello(language_code)
end

def hello(name, language_code) when is_binary(name) do
phrase(language_code) <> name
end

defp phrase("en"), do: "Hello, "
defp phrase("es"), do: "Hola, "
end

iex> Greeter.hello ["Sean", "Steve"]
"Hello, Sean, Steve"

iex> Greeter.hello ["Sean", "Steve"], "es"
"Hola, Sean, Steve"
``````