맵 타입

맵 타입 (Map types)

맵(map)은 Go에서 아주 자주 만나는 타입이에요. 배열이나 슬라이스가 숫자 인덱스로 요소를 찾았다면, 맵은 키(key)라는 값으로 요소를 찾는 구조입니다. 잘만 쓰면 데이터를 훨씬 자연스럽게 다룰 수 있죠. 이번에는 맵이 정확히 무엇이고, 어떤 제약이 있는지 차근차근 살펴볼게요.

출처: Go Specification

본문

맵은 하나의 타입으로 이루어진 요소들의 순서 없는 집합이에요. 이때 요소들의 타입을 element type(요소 타입)이라고 부르고, 다른 타입의 유일한 키(key)들의 집합으로 인덱싱됩니다. 그 키들의 타입을 key type(키 타입)이라고 해요. 그리고 초기화되지 않은 맵의 값은 nil입니다.

맵 타입의 문법은 이렇게 생겼어요.

MapType = "map" "[" KeyType "]" ElementType .
KeyType = Type .

map 키워드 뒤에 대괄호 안에 KeyType, 그 뒤에 ElementType이 오는 형태죠. 보기보다 간단하니까 실제 예시로 바로 확인해 보게요.

map[string]int
map[*T]struct{ x, y float64 }
map[string]interface{}

여기서 한 가지 중요한 제약이 있습니다. 키 타입의 피연산자에 대해 비교 연산자 ==!=가 완전히 정의되어 있어야 해요. 그러니까 키 타입은 함수(function), 맵(map), 슬라이스(slice)가 되면 안 됩니다. 이 세 가지는 비교 자체가 안 되는 타입이기 때문이에요.

만약 키 타입이 인터페이스 타입이라면, 비교 연산자가 동적 키 값(dynamic key value)에 대해 정의되어 있어야 합니다. 그렇지 않으면 실행 중에 run-time panic이 발생해요. 키를 비교할 수 없어서 맵 동작 자체가 불가능해지기 때문이죠.

맵 요소의 개수를 맵의 길이(length)라고 불러요. 맵이 m일 때 내장 함수 len으로 알아낼 수 있고, 실행 중에 이 값은 달라질 수 있습니다. 요소는 실행 중에 할당문을 이용해 추가하고, 인덱스 표현식으로 가져올 수 있어요. 제거할 때는 내장 함수 deleteclear를 사용하면 됩니다.

새로운 빈 맵 값은 내장 함수 make로 만들 수 있어요. make는 맵 타입과 선택적인 용량 힌트(capacity hint)를 인자로 받습니다.

make(map[string]int)
make(map[string]int, 100)

이때 중요한 건 초기 용량이 맵의 크기를 제한하지 않는다는 점이에요. 맵은 저장된 항목 수에 맞춰 스스로 커지죠. 단, nil 맵은 예외입니다. nil 맵은 빈 맵과 동등하지만, 요소를 추가할 수 없다는 차이가 있어요.

더 알아보기

  • 맵에서 요소를 제거하는 방법은 delete와 clear 섹션에서 더 자세히 다뤄요.
  • 맵을 만드는 make의 동작은 slices, maps and channels 만들기에서 확인할 수 있어요.
  • 키로 사용할 수 없는 타입이 왜 제한되는지 궁금하다면 비교 연산자 문서를 함께 보면 이해가 쉬워요.