Elixir 의 = 과 ^
엘릭서를 처음 배우면 = 때문에 헷갈리는 일이 있다.
다른 언어는 = 을 대입연산자라고 부른다.
하지만 엘릭서는 매칭연산자라고 부른다.
=는 패턴 매칭임
양쪽이 맞으면 변수에 값 바인딩 됨.
x = 1
# x == 1
{a, b} = {1, 2}
# a == 1, b == 2
즉, =는 “대입”이라기보다 양쪽 맞추기임.
매칭 실패도 있음
{a, b} = {1, 2, 3}
# MatchError
1 = 2
# MatchError
양쪽 안 맞으면 바로 MatchError 터짐.
즉, =는 검사 + 바인딩 같이 하는 특별한 연산자임.
변수는 재바인딩 가능
문제는 이미 값 있는 변수도 다시 바인딩됨.
x = 1
x = 2
# x == 2
{x, y} = {3, 4}
# x == 3, y == 4
엘릭서 변수는 기본적으로 재바인딩 허용.
유연하긴 한데, 의도 헷갈릴 때 많음.
그래서 ^ 필요함
“이 값 그대로여야 한다” 강제하고 싶으면 핀 연산자(^) 씀.
x = 1
{^x, y} = {1, 2}
# 성공. y == 2
{^x, y} = {2, 3}
# MatchError. x는 1이어야 함
핀은 변수 값 고정시켜놓고 매칭 돌림.
즉, 재바인딩 막고 값 고정 기능임.
예제 모음
1. case에서
user_id = 42
case {:ok, 42} do
{:ok, ^user_id} -> :same_user
{:ok, _} -> :different_user
end
# :same_user
핀 없으면 첫 절이 항상 실행됨. 버그 소스 됨.
2. 함수 인자에서
def update(^id, %{id: id} = rec, params), do: apply_changes(rec, params)
def update(_, rec, _), do: {:error, :id_mismatch}
API나 DB에서 ID 반드시 같아야 하는 상황 → 핀으로 바로 표현 가능.
3. 맵/바이너리
%{type: ^expected} = %{type: "image/png", size: 200}
# 매치 성공
<< "image/", ^subtype :: binary >> = "image/png"
# subtype == "png"
데이터 구조 분해하면서 값 고정 가능.
프로토콜 파싱이나 검증에 유용함.
언제 쓰지 말까
모든 검증을
^로 때려넣으면 가독성 박살남값이 바뀌는 게 핵심인 코드에 쓰면 유지보수 지옥됨
👉 진짜 “이 값이어야만 한다” 규칙 있을 때만 쓰는 게 정석임.
실무에서 가치
API 요청 검증: URL 파라미터 ID랑 바디 ID 같아야 함
GenServer 상태 전이: 특정 상태일 때만 이벤트 허용
DB 무결성: 참조 일치 여부 확인
핀 쓰면 if문보다 자연스럽고, 의도 코드에 바로 드러남.
한 줄 요약
엘릭서에서 =은 대입 아님. 패턴 매칭임.
그리고 ^는 변수 고정해서 “이 값이어야 한다” 명시하는 도구임.