🔑 제네릭을 사용해 Go에서 맵(Map)의 정렬된 키 가져오기 🔗

Go에서 맵(map)은 본질적으로 순서가 없습니다. for range 루프를 사용해 맵을 순회하면 순회 순서가 무작위로 결정됩니다. 제네릭이 도입되기 전에는 개발자들이 맵의 키를 추출하고 정렬하기 위해 보일러플레이트 코드나 타입별 전용 함수를 일일이 작성해야 했습니다.

현대적인 Go 제네릭과 표준 라이브러리 패키지(cmp 및 slices)를 사용하면 깔끔하고 재사용 가능한 SortedKeys 함수를 매우 직관적이고 간결하게 구현할 수 있습니다.

📑 목차 🔗


💻 최신 구현 방식 (Go 1.21+) 🔗

package main

import (
	"cmp"
	"slices"
	"fmt"
)

// SortedKeys는 맵에서 모든 키를 추출하여 정렬된 순서로 반환합니다.
// 키 타입이 순서 비교가 가능한(정수, 부동소수점, 문자열 등) 모든 맵에서 동작합니다.
func SortedKeys[K cmp.Ordered, V any](m map[K]V) []K {
	r := make([]K, 0, len(m))
	for k := range m {
		r = append(r, k)
	}
	slices.Sort(r)
	return r
}

func main() {
	// 예제 1: 정수형 키
	intMap := map[int]string{3: "three", 1: "one", 2: "two"}
	fmt.Println(SortedKeys(intMap))
	// 출력: [1 2 3]

	// 예제 2: 문자열 키
	strMap := map[string]int{"banana": 2, "apple": 4, "cherry": 1}
	fmt.Println(SortedKeys(strMap))
	// 출력: [apple banana cherry]
}

⚙️ 작동 원리 🔗

  1. 제네릭 타입 제약 조건 (K cmp.Ordered, V any):
    • K cmp.Ordered는 맵의 키를 정수, 부동소수점, 문자열처럼 비교 연산자(<, >, <=, >=)를 지원하는 타입으로 제한합니다.
    • V any는 맵의 값이 어떤 타입이든 될 수 있도록 허용합니다(any는 interface{}의 별칭입니다).
  2. 슬라이스 사전 할당:
    • make([]K, 0, len(m))는 맵의 길이와 동일한 용량(capacity)을 가진 슬라이스를 미리 할당하여, append 루프 도중 비용이 많이 드는 동적 메모리 재할당이 발생하지 않도록 합니다.
  3. 키 추출:
    • for k := range m 루프가 모든 키를 슬라이스에 수집합니다.
  4. 정렬:
    • slices.Sort(r)는 고도로 최적화된 Go의 정렬 알고리즘을 사용해 키 슬라이스를 제자리(in-place)에서 정렬합니다.

🚀 2020년 초안보다 이 버전이 훨씬 더 나은 이유 🔗

Go 제네릭이 아직 설계 초안(design draft) 단계였던 2020년 6월에는 개발자가 sort.Interface를 충족하는 커스텀 타입을 수동으로 구현해야 했습니다.

// Go 1.18 이전 설계 초안 방식 (현재는 사용되지 않음)
type Ordered interface {
	type int, int8, ... // 인터페이스 내 타입 리스트
}

type orderedSlice[T Ordered] []T
func (s orderedSlice[T]) Len() int           { return len(s) }
func (s orderedSlice[T]) Less(i, j int) bool { return s[i] < s[j] }
func (s orderedSlice[T]) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

오늘날 현대적인 Go는 다음을 기본으로 제공합니다.


📚 무료 전자책 다운로드 🔗

카우에의 삶의 방식 오프라인 에디션을 받아보세요—🍏 건강, 💰 부, ❤️ 사랑, 🧘 의미를 최적화하기 위한 실전 가이드입니다.

카우에의 삶의 방식

카우에의 삶의 방식

📬 뉴스레터 구독하기 🔗

더 나은 삶을 위한 새로운 에세이, 도서 요약, 실전 가이드를 발행할 때 알림을 받아보세요. 스팸은 없으며 언제든 구독을 취소할 수 있습니다.


💬 댓글 및 토론 🔗

질문, 의견 또는 제안이 있으신가요? 아래에 생각을 남겨주세요. 댓글은 GitHub Discussions(광고 및 스팸 없음)를 통해 제공됩니다—댓글이나 반응을 남기려면 아래의 GitHub으로 로그인을 클릭하세요(무료 GitHub 계정은 1분 이내에 만들 수 있습니다).



최종 업데이트: 2026. 10. 11..

면책 조항: 본 사이트의 콘텐츠는 정보 제공 및 교육 목적으로만 제공되며 의학, 심리, 재무, 투자, 세무 또는 법률 자문을 구성하지 않습니다. 여기에 제시된 생각, 큐레이션 및 의견은 전적으로 저 개인의 것이며 고용주의 입장을 대변하지 않습니다. 도서, 강연 및 아티클 요약은 독립적인 교육적 해설이며 각 저자의 지적 재산입니다. 편집, 서식 지정 및 요약을 돕기 위해 AI 도구가 사용될 수 있으며, 정확성을 기하기 위해 최선을 다하고 있으나 오류가 포함될 수 있습니다. 개인정보 처리방침: 본 사이트는 선택적 뉴스레터 구독(follow.it), 댓글(giscus / GitHub Discussions) 및 임베디드 미디어(YouTube)를 위해 제3자 서비스를 사용하며, 해당 서비스들은 각자의 개인정보 처리방침에 따라 방문자의 IP 주소와 쿠키를 처리할 수 있습니다.