수색…


익명 함수

Elixir에서는 익명의 함수를 사용하는 것이 일반적입니다. 익명의 함수를 만드는 것은 간단합니다.

iex(1)> my_func = fn x -> x * 2 end
#Function<6.52032458/1 in :erl_eval.expr/5>

일반적인 구문은 다음과 같습니다.

fn args -> output end

가독성을 위해 인수를 괄호로 묶을 수 있습니다.

iex(2)> my_func = fn (x, y) -> x*y end
#Function<12.52032458/2 in :erl_eval.expr/5>

익명의 함수를 호출하려면 할당 된 이름으로 호출하고 추가하십시오 . 이름과 논증 사이.

iex(3)>my_func.(7, 5)
35

인수없이 익명 함수를 선언 할 수 있습니다.

iex(4)> my_func2 = fn -> IO.puts "hello there" end
iex(5)> my_func2.()
hello there
:ok

캡처 연산자 사용

익명 함수를보다 간결하게 만들려면 & 연산자를 사용할 수 있습니다. 예를 들어, 대신 :

iex(5)> my_func = fn (x) -> x*x*x end

당신은 쓸 수 있습니다:

iex(6)> my_func = &(&1*&1*&1)

매개 변수가 여러 개인 경우 각 인수에 해당하는 숫자를 1 부터 계산하십시오.

iex(7)> my_func = fn (x, y) -> x + y end

iex(8)> my_func = &(&1 + &2)   # &1 stands for x and &2 stands for y

iex(9)> my_func.(4, 5)
9

여러 단체

익명 함수는 또한 패턴 일치 의 결과로 여러 개의 본문을 가질 수 있습니다.

my_func = fn
  param1 -> do_this
  param2 -> do_that
end

여러 본문이있는 함수를 호출 할 때 Elixir는 제공 한 매개 변수를 적절한 함수 본문과 일치 시키려고 시도합니다.

함수 목록으로 키워드 목록

여러 키 - 값 쌍이 포함 된 'options'스타일 매개 변수에 키워드 목록 사용 :

def myfunc(arg1, opts \\ []) do
  # Function body
end

위의 함수를 다음과 같이 호출 할 수 있습니다.

iex> myfunc "hello", pizza: true, soda: false

이는 다음과 같습니다.

iex> myfunc("hello", [pizza: true, soda: false])

인수 값은 opts.pizzaopts.soda 각각 사용할 수 있습니다.
또는 원자 : opts[:pizza]opts[:soda] 있습니다.

명명 된 함수와 개인 함수

명명 된 함수

defmodule Math do
    # one way
    def add(a, b) do
        a + b
    end

    # another way
    def subtract(a, b), do: a - b
end

iex> Math.add(2, 3)
5
:ok
iex> Math.subtract(5, 2)
3
:ok

개인 기능

defmodule Math do
    def sum(a, b) do
        add(a, b)
    end

    # Private Function
    defp add(a, b) do
        a + b
    end
end

iex> Math.add(2, 3)
** (UndefinedFunctionError) undefined function Math.add/2
Math.add(3, 4)
iex> Math.sum(2, 3)
5

패턴 매칭

Elixir는 인수의 값을 기반으로 본문에 대한 함수 호출을 찾습니다.

defmodule Math do
    def factorial(0): do: 1
    def factorial(n): do: n * factorial(n - 1)
end

여기서 양수의 계승은 두 번째 절과 일치하고 factorial(0) 은 첫 번째 절과 일치합니다. (단순함을 위해 음수는 무시함). Elixir는 함수를 위에서 아래로 일치시킵니다. 두 번째 함수가 첫 번째 함수 위에 쓰여지면 끝없는 재귀로 넘어가 예상치 못한 결과가 발생합니다. factorial(0)factorial(n) 과 일치하기 때문에,

가드 조항

Guard 절을 사용하면 함수를 실행하기 전에 인수를 확인할 수 있습니다. 가드 조항은 일반적으로 선호하는 ifcond 인해 가독성 및 만들기 위해 특정 최적화 기법 컴파일러에 쉽게. 모든 가드가 일치하는 첫 번째 함수 정의가 실행됩니다.

다음은 가드와 패턴 매칭을 사용하는 계승 함수의 구현 예입니다.

defmodule Math do
    def factorial(0), do: 1
    def factorial(n) when n > 0: do: n * factorial(n - 1)
end

첫 번째 패턴은 인수가 0 경우에만 일치합니다 (유일한 경우). 인수가 0 이 아니면 패턴 일치가 실패하고 아래의 다음 함수가 점검됩니다.

두 번째 함수 정의에는 가드 절이 있습니다. when n > 0 입니다. 즉,이 함수는 인수 n0 보다 큰 경우에만 일치합니다. 결국, 수학 계승 함수는 음의 정수에 대해 정의되지 않습니다.

함수 정의 (패턴 일치 및 guard 절 포함)가 일치하지 않으면 FunctionClauseError 가 발생합니다. 음수에 대해 정의되지 않았기 때문에 음수를 인수로 전달할 때이 함수에 대해 발생합니다.

FunctionClauseError 자체는 실수가 아닙니다. 다른 언어에서 흔히있는 -1 또는 0 또는 다른 "오류 값"을 반환 -1 오류의 원인을 숨기고 정의되지 않은 함수를 호출하여 향후 개발자에게 큰 곤란을 줄 수 있습니다.

기본 매개 변수

구문을 사용하여 명명 된 함수에 기본 매개 변수를 전달할 수 있습니다. param \\ value :

defmodule Example do
    def func(p1, p2 \\ 2) do
        IO.inspect [p1, p2]
    end
end

Example.func("a")    # => ["a", 2]
Example.func("b", 4) # => ["b", 4]

캡처 기능

다른 모듈의 기능을 캡처하려면 & 를 사용하십시오. 캡쳐 된 함수를 함수 매개 변수 또는 익명 함수 내에서 직접 사용할 수 있습니다.

Enum.map(list, fn(x) -> String.capitalize(x) end)

& 사용하여보다 간결하게 만들 수 있습니다.

Enum.map(list, &String.capitalize(&1))

인수를 전달하지 않고 함수를 캡처하려면 명시 적으로 해당 인수를 지정해야합니다 (예 : &String.capitalize/1 :

defmodule Bob do
  def say(message, f \\ &String.capitalize/1) do
    f.(message)
  end
end


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow