06 Map 맵

Go language course for beginners


Go에서의 맵은 기본적으로 Hash Table 입니다.

맵은 키를 이용해 값을 찾는 자료구조입니다.

Go에서의 맵은 나중에 자세히 다루겠지만, 동시성을 지원하지 않습니다.

따라서 동시 접근이 필요한 경우에는 "sync.Map"을 사용하면 편리합니다.

맵은 map[키타입]값타입 형태로 선언합니다.

var m map[string]int

fmt.Println(m) // map[]

fmt.Println(m == nil) // true

Map의 Zero Value는 nil이며 사용전에 초기화가 필요합니다.

맵 리터럴은 기본적으로 초기화된 상태이며 따로 초기화가 필요하지 않습니다.

m := map[string]string{
    "A": "Alfa",
    "B": "Bravo",
    "C": "Charlie",
    "D": "Delta",
    "E": "Echo",
    "F": "Foxtrot",
}

fmt.Println(m) // map[A:Alfa B:Bravo C:Charlie D:Delta E:Echo F:Foxtrot]

fmt.Println(m == nil) // false

비어있는 맵은 make를 이용해 생성합니다.

m := make(map[string]int)

fmt.Println(m) // map[]

fmt.Println(m == nil) // false

맵에 키를 추가하는 방법은 m[키] = 값 형태로 대입하면 새로운 키와 값이 추가됩니다. 만약 키가 이미 존재하면 기존 값을 대입합니다.

삭제는 delete(m, 키) 형태로 삭제합니다.

맵의 키에 해당하는 값을 가져오려면 m[키] 형태로 가져옵니다.

맵에 키가 존재하는지 확인이 필요한 경우에는 value, ok := m[키] 형태로 값을 가져옵니다.

ok가 false인 경우에는 키가 존재하지 않습니다.

또한 for range를 이용해 맵을 순회할 수 있습니다.

m := map[string]string{
    "A": "Alfa",
    "B": "Bravo",
    "C": "Charlie",
    "D": "Delta",
    "E": "Echo",
    "F": "Foxtrot",
}

for key, value := range m {
    fmt.Println(key, value)
}

// 순회 순서는 임의로 정해지며 순서는 보장되지 않습니다.
// F Foxtrot
// A Alfa
// B Bravo
// C Charlie
// D Delta
// E Echo

단 이런 방식은 맵의 키의 순회 순서를 보장하지 않습니다.

실행시마다 맵의 키의 순회 순서는 다를 수 있습니다.

또한 맵을 for range문으로 순회하는 도중에 맵의 원소를 삭제하는것은 허용됩니다.

m := map[string]string{
    "A": "Alfa",
    "B": "Bravo",
    "C": "Charlie",
    "D": "Delta",
    "E": "Echo",
    "F": "Foxtrot",
}

for key := range m {
    delete(m, key)
}

fmt.Println(m) // map[]

맵은 추가와 삭제가 자유롭다는 점 때문에 여러 용도로 사용할 수 있습니다.

가장 기본적으로 Hash Set 처럼 사용하는 경우에는 map[키타입]struct{} 형태로 사용하는 경우도 있습니다.

하지만 동시에 맵은 상당히 메모리를 사용하기 때문에 필요한 경우에만 적절히 사용하는 것이 좋습니다.

What's next?

다음 포스트에서는 Go에서의 포인터에 대하여 알아보겠습니다.