Elixir에서 할당문은 일반적으로 우리가 생각하는 할당문과 다릅니다.
따라서, Elixir를 이해하려면 먼저 Elixir의 할당방법을 이해해야합니다.
일반적인 프로그래밍 언어에서의 등호(=)와 수학에서 쓰이는 등호(=)와 비교해봅시다.
x=a+1 이라는 방정식이 있을때 우리는 x에 a+1의 값을 할당하지 않습니다.
그저 x와 a+1이 같은 값인지를 확인할 뿐입니다.
x의 값을 알고 있다면 a의 값을 알아낼 수 있으며, 반대도 마찬가지 입니다.
Elixir의 등호(=)도 이와 비슷합니다.
iex> a = 1
1
iex> b = a + 2
3
위의 코드를 보면 일반적으로 변수 a에 정수값 1을 할당 했고, 다음 코드에서 a에 2를 더해서 b에는 3이 할당 되었다고 생각할 수 있습니다.
그러나 Elixir에서 '=' 기호는 다른 언어처럼 값을 할당해주는 '대입 연산자'가 아닙니다.
방정식의 등호(=)처럼 동작하는 매치연산자 입니다.
그럼 대입연산자와 어떻게 다른지 다음의 코드를 보겠습니다.
iex> a = 1
1
iex> 1 = a
1
iex> 2 = a
** (MatchError) no match of right hand side value: 1
Elixir의 '=' 기호는 할당문이 아니라 단언문처럼 동작합니다.
즉, 먼저 좌변과 우변이 같아 질 방법이 있는지 평가를 합니다.
먼저,,,
코드 첫째줄(a = 1)에서 a가 1과 같아 질 방법이 있는지(매칭될 방법이 있는지) 평가를 합니다.
(중요-*Elixir에서는 변수가 좌변에 있을때만 변숫값을 변경할 수 있습니다.)
매칭을 참으로 만들기 위해서, 현재 값이 없는 a에 정수값 1이 바인딩되고 정상적으로 실행이 됩니다.
코드 둘째줄 (1 = a)에서도 1이 a와 같아질 방법이 있는지 평가를 합니다.
앞에서 이미 a에 1을 바인딩해서, 1과 a는 같아 질 수 있으므로(매칭될 수 있으므로) 문제없이 실행됩니다.
하지만,
코드 셋째줄 (2 = a)에서 2는 a에 바인딩 되어있는 1과 같아지게 할 방법이 없으므로(매칭을 참으로 만들 수 없으므로) 매치에러가 발생하게 됩니다.
(중요-*Elixir에서는 변수가 좌변에 있을때만 변숫값을 변경할 수 있습니다.)
이렇게,,,
Elixir에서는 변수에 값을 할당할때 매치연산자를 사용하여 좌변과 우변이 매칭될 수 있는지 평가한 후 값을 할당합니다.
Elixir에서는 리스트를 대괄호와 쉼표를 이용하여 다음과 같이 만듭니다.
[1, 2, 3]
iex> list = [1, 2, 3]
[1, 2, 3]
iex> [a, b, c] = list
[1, 2, 3]
iex> a
1
iex> b
2
iex> c
3
list = [1, 2, 3]은 매칭을 참으로 만들기위해 변수 list에는 [1, 2, 3]이 바인딩 되었습니다.
[a, b, c] = list에서 매치연산자를 사용하여 Elixir는 좌변과 우변을 같게 만들 방법을 찾습니다.
좌변은 변수 a,b,c 세 개를 담은 리스트고, 우변은 1, 2, 3 세 개의 값을 담은 리스트입니다.
따라서 각 변수마다 위치에 맞는 값을 바인딩하면 양변이 같아지게 됩니다.
(a=1,b=2,c=3)
이러한 과정을 패턴매칭이라고 합니다.
패턴(좌변)과 값(우변)의 구조가 서고 같고, 패턴과 값의 각 요소를 짝지을 수 있다면 매칭에 성공하게 됩니다.
패턴매칭의 예를 좀 더 확인해 봅시다.
iex> list = [1, 2, [3, 4, 5]]
[1, 2, [3, 4, 5]]
iex> [a, b, c] = list
[1, 2, [3, 4, 5]]
iex> a
1
iex> b
2
iex> c
[3, 4, 5]
위의 예제에서는 매칭에 성공하기위해 변수 c에 리스트 [3, 4, 5] 가 바인딩 되었습니다.
iex> list = [1, 2, 3]
[1, 2, 3]
iex> [a, 2, c] = list
[1, 2, 3]
iex> a
1
iex> c
3
위의 예제에서는 패턴 안에 있는 리터럴 2는 우변의 같은자리에 있는 값과 매칭되므로, a와 c에는 각각 1과 3의 값이 바인딩되었습니다.
iex> list = [1, 2, 3]
[1, 2, 3]
iex> [a, 1, c] = list
** (MatchError) no match of right hand side value: [1, 2, 3]
한편 위의 예제에서는 좌변의 리터럴 1가 우변의 같은 위치의 값인 2와 매칭이 되지않아 에러가 발생하게 됩니다.
언더스코어(_)는 패턴(좌변)에서 변수처럼 동작하지만 주어진 값을 바로 버립니다.
패턴매칭에서 모든 값을 받아들이는 와일드카드로 사용할 수 있습니다.
iex> [a, _, _] = [1, 2, 3]
[1, 2, 3]
iex> a
1
iex> [a, _, _] = ["a", "b", "c"]
["a", "b", "c"]
iex> a
"a"
iex> a = 1
1
iex> a = 2
2
iex> 2 = a
2
iex> ^a = 3
** (MatchError) no match of right hand side value: 3
iex> ^a = 2
2
Elixir에서는 기본적으로 좌변에 변수가 있고
매치연산자(=)를 사용하면,
매치연산자가 좌변과 우변을 맞추기위해 변수에 새로운 값을 할당합니다.
그렇다면 좌변에 변수가 있을때, 값을 새로 할당하지않고 (2 = a) 처럼
비교만 하고싶을때는 어떻게 해야할까요?
변수 앞에 핀 연산자(^)를 사용하여 값을 고정시켜,
매치연산자로(=) 값이 서로 맞는지만 비교합니다.