Map — Elixir의 키-값 데이터 구조
Map — Elixir의 키-값 데이터 구조
Map은 Elixir에서 "가장 많이 쓰는"(go to) 키-값(key-value) 데이터 구조예요. 어떤 값이든 키가 될 수 있고, 특정 키에 연결된 값을 빠르게 꺼내고 싶을 때 거의 항상 Map을 먼저 떠올리게 되죠.
출처: Map
본문
Map은 %{} 문법으로 만들 수 있고, 키-값 쌍은 key => value처럼 표현해요:
iex> %{}
%{}
iex> %{"one" => :two, 3 => "four"}
%{3 => "four", "one" => :two}
Map 안의 키-값 쌍은 어떤 순서도 따르지 않아요. 그래서 위 예시에서 출력된 Map이 처음 만들었을 때와 순서가 달라 보이는 거예요. 정렬된 구조가 아니라 "연관" 구조라는 점을 그대로 드러내는 부분이죠.
Map은 키의 타입에 아무 제약을 두지 않아요. 어떤 값이든 키가 될 수 있어요. 다만 키-값 구조인 만큼 중복 키는 허용하지 않아요. 키는 정확히 일치하는지 보는 ===/2 연산자로 비교해요. 그리고 리터럴 안에 서로 충돌하는 키가 정의되면 마지막 키가 이겨요.
키-값 쌍의 키가 atom이라면 key: value 단축(shorthand) 문법을 쓸 수 있어요. 다른 여러 특수 형태에서 쓰는 표기와 같은 방식이에요:
iex> %{a: 1, b: 2}
%{a: 1, b: 2}
단축 문법을 =>와 섞어 쓰고 싶다면, 단축 문법이 반드시 마지막에 와야 해요:
iex> %{"hello" => "world", a: 1, b: 2}
%{:a => 1, :b => 2, "hello" => "world"}
Map의 키는 이 모듈의 함수들(Map.get/3, Map.fetch/2 등)이나 Access 모듈이 제공하는 map[] 문법으로 접근할 수 있어요:
iex> map = %{a: 1, b: 2}
iex> Map.fetch(map, :a)
{:ok, 1}
iex> map[:b]
2
iex> map["non_existing_key"]
nil
atom 키라면 map.key 표기를 쓸 수도 있어요. 이때 주의할 점이 있는데, map.key는 map에 :key라는 키가 없으면 KeyError를 일으켜요. 반면 map[:key]는 키가 없으면 그냥 nil을 돌려주죠:
map = %{foo: "bar", baz: "bong"}
map.foo
#=> "bar"
map.non_existing_key
** (KeyError) key :non_existing_key not found in:
...
괄호 피하기
필드에 접근할 때 data.key()처럼 괄호를 붙이지 마세요. 괄호를 쓰면 Elixir는 data가 모듈을 나타내는 atom이라고 해석해서, 그 모듈 안에 key/0 함수가 있는지 호출해 보려고 해요. 그러니까 필드 접근이 아니라 다른 의미로 읽히게 된다는 점을 기억해 두세요.