본문 바로가기
프로그래밍

👨‍💻 [Go] Go 에서 map 이란 무엇이며, 어떻게 활용할 수 있나요?

by 밝음의기둥 2025. 1. 6.
반응형

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."


👨‍💻 안녕하세요, 윌리 프로젝트의 윌리 입니다.

Go 에서 map 이란 무엇이며, 어떻게 활용할 수 있는지 간략히 알아보았습니다.


질문 >

Go 에서 map 이란 무엇이며, 어떻게 활용할 수 있나요?

답변 >

Go에서 맵(Map) 이란?

맵(Map)은 Go에서 제공하는 데이터 구조로, 키(key)값(value)의 쌍을 저장하고 관리합니다.

맵은 다른 언어의 해시 테이블(Hash Table)이나 딕셔너리(Dictionary)와 비슷하며, 데이터 조회와 삽입이 상수 시간(O(1))에 이루어질 수 있는 효율적인 구조입니다.


맵의 주요 특징

  1. 키-값 저장:
    • 키는 고유해야 하며, 값은 중복될 수 있습니다.
    • 키는 해시 가능(Hashable) 타입이어야 합니다. (예: 문자열, 숫자, 불리언, 포인터 등)
  2. 동적 크기:
    • 맵은 동적 크기를 가지며, 데이터가 추가될 때 크기가 자동으로 조정됩니다.
  3. 제로 값:
    • 맵의 제로 값은 nil입니다. nil 맵은 읽기만 가능하며, 수정하거나 새 데이터를 추가할 수 없습니다.

맵 선언 및 초기화

1. make 함수로 맵 생성

m := make(map[string]int) // 키: string, 값: int

2. 리터럴을 사용한 맵 생성

m := map[string]int{
    "apple":  2,
    "banana": 5,
}

3. 제로 값 맵 (nil 맵)

var m map[string]int // nil 맵
fmt.Println(m)       // map[]


맵 사용법

1. 데이터 삽입

m := make(map[string]int)
m["apple"] = 2
m["banana"] = 5
fmt.Println(m) // map[apple:2 banana:5]

2. 데이터 조회

fmt.Println(m["apple"])  // 2
fmt.Println(m["orange"]) // 0 (키가 없으면 타입의 제로 값 반환)

3. 키 존재 여부 확인

Go에서는 키가 존재하지 않는 경우를 구분하기 위해 두 번째 반환값을 활용합니다.

value, ok := m["orange"]
if ok {
    fmt.Println("키가 존재:", value)
} else {
    fmt.Println("키가 없음")
}

4. 데이터 삭제

delete(m, "apple")
fmt.Println(m) // map[banana:5]

5. 맵 길이 확인

fmt.Println(len(m)) // 1 (맵에 있는 키-값 쌍의 개수)


맵과 반복문

맵의 모든 키-값 쌍에 대해 반복하려면 for 루프와 range를 사용합니다.

m := map[string]int{
    "apple":  2,
    "banana": 5,
    "cherry": 7,
}

for key, value := range m {
    fmt.Printf("%s: %d\\n", key, value)
}

참고: 맵의 순서는 고정되지 않으며, 반복할 때마다 순서가 달라질 수 있습니다. 특정 순서가 필요하다면, 키를 슬라이스에 복사한 뒤 정렬하여 사용해야 합니다.


예제: 맵 활용

1. 단어 빈도 계산

package main

import (
    "fmt"
    "strings"
)

func main() {
    text := "go is great and go is fast"
    words := strings.Fields(text)

    wordCount := make(map[string]int)
    for _, word := range words {
        wordCount[word]++
    }

    fmt.Println(wordCount) // map[and:1 fast:1 go:2 great:1 is:2]
}

2. 키의 정렬된 순서로 출력

package main

import (
    "fmt"
    "sort"
)

func main() {
    m := map[string]int{
        "apple":  2,
        "banana": 5,
        "cherry": 7,
    }

    keys := make([]string, 0, len(m))
    for key := range m {
        keys = append(keys, key)
    }

    sort.Strings(keys)

    for _, key := range keys {
        fmt.Printf("%s: %d\\n", key, m[key])
    }
}

3. 복합 타입을 키 또는 값으로 사용하는 맵

맵은 구조체를 값으로 사용할 수 있으며, 경우에 따라 키로도 사용할 수 있습니다(해시 가능 타입인 경우).

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    m := make(map[string]Person)
    m["john"] = Person{"John", 30}
    m["jane"] = Person{"Jane", 25}

    fmt.Println(m) // map[jane:{Jane 25} john:{John 30}]
}


맵의 장점

  • 빠른 데이터 조회: 키를 기반으로 상수 시간에 값을 조회할 수 있습니다.
  • 동적 크기 조정: 추가 데이터를 처리하기 위해 크기를 동적으로 조정합니다.
  • 간단한 데이터 관리: 키를 사용해 데이터를 쉽게 삽입, 삭제, 조회할 수 있습니다.

맵 사용 시 주의 사항

  • 키 타입:
    • 키는 반드시 해시 가능 타입이어야 합니다.
    • 예: 문자열, 숫자, 불리언, 포인터, 배열, 구조체(내부에 해시 가능 타입만 포함).
  • nil 맵:
    • nil 맵은 읽기만 가능하며, 데이터 삽입 시 런타임 에러가 발생합니다.
var m map[string]int
m["apple"] = 1 // panic: assignment to entry in nil map

  • 순서 없음:
    • 맵은 키-값 쌍의 순서를 보장하지 않습니다.
    • 순서가 필요하면 키를 슬라이스에 저장한 뒤 정렬해야 합니다.
  • 성능 고려:
    • 맵은 메모리를 많이 사용하는 데이터 구조입니다.
    • 성능이 중요한 경우, 맵 사용을 신중히 고려해야 합니다.

맵은 Go에서 가장 강력하고 효율적인 데이터 구조 중 하나로, 데이터를 키로 관리하는 모든 경우에 적합합니다. 다양한 데이터 관리 시나리오에서 적절히 활용하면 코드의 가독성과 효율성을 높일 수 있습니다.



🎬 유튜브 채널 🎬

 

위로그@WiLog

📢 안녕하세요, 위로그@WiLog 시청자 여러분, 저는 윌리(Willee) 입니다. 📢 위로그@WiLog 는 자기계발을 목적으로 하는 채널 입니다. 📢 오늘도 즐겁게~ 자신을 위한 계발을 함께 해보아요~ d^_^b 📌

www.youtube.com

🎬 치지직 채널 🎬

 

위로그 채널 - CHZZK

지금, 스트리밍이 시작됩니다. 치지직-

chzzk.naver.com


반응형