Go 언어 1.28 표준 라이브러리에 제네릭 컬렉션 타입 추가 제안
Go 언어 개발팀이 제네릭을 활용한 다양한 컬렉션 데이터 구조(Set, Map, Heap 등)를 표준 라이브러리에 추가하는 제안을 발표했습니다. 그동안 부족했던 기본 자료구조와 불편했던 세트(Set) 구현 방식을 개선하여 개발자 편의성과 성능을 크게 높일 수 있는 중요한 업데이트입니다. 향후 Go 1.28 버전에서 정식으로 도입될 예정입니다.
배경: Go 컬렉션 워킹 그룹은 Go의 익숙한 원칙인 실용주의와 단순성을 바탕으로, 일반적인 컬렉션 데이터 구조를 표준 라이브러리에 도입하기 위해 2025년 말에 결성되었습니다. 이 그룹은 Jonathan Amsterdam, Alan Donovan, Robert Griesemer, Daniel Martí, Roger Peppe, Keith Randall, 그리고 Ian Lance Taylor로 구성되어 있습니다. 이제 우리는 논의 결과를 커뮤니티와 공유할 준비가 되었습니다. 이 이슈는 Go 1.28을 위한 새로운 컬렉션 API에 대한 여러 관련 제안을 논의하기 위한 포괄적인 페이지입니다. 주요 테마에 대한 높은 수준의 개요를 제시하며, 구체적인 제안 및 관련 구현 코드(CL) 링크를 제공합니다.
Go는 현재 라이브러리에서 제공하는 컬렉션 타입이 거의 없으며, 처음부터 언어에 내장된 슬라이스(Slice)와 맵(Map) 타입의 유연성을 강조해 왔습니다. 제공되는 것 중 가장 중요한 것은 우선순위 큐에 사용되는 힙(Heap)입니다. 심지어 세트(Set)조차도 부재하여, 전통적으로 map[T]bool 또는 map[T]struct{}로 표현해 왔습니다. 이진 트리를 기반으로 하는 순서가 있는 맵과 세트는 전혀 존재하지 않았습니다.
하지만 Go 1.18에 제네릭(Generics)이 추가되고 Go 1.23에 이터레이터(Iterators)가 도입되면서, 라이브러리에서 정의한 타입이 내장 타입과 비슷한 수준의 인체공학적(사용하기 편리한) 설계를 갖출 수 있게 되었고, 슬라이스와 맵에 대한 많은 일반적인 작업들을 라이브러리 함수 호출로 표현할 수 있게 되었습니다. 이 작업은 몇 가지 중요한 데이터 타입을 표준 라이브러리에 추가하고, 향후 추가될 기능들을 위한 API 규칙을 확립하는 것을 목표로 합니다.
제안: 제안된 추가 사항은 다음과 같습니다:
#70471, CL 657296 (Go 1.27에 릴리스됨): hash/maphash.Hasher: 임의의 데이터 타입에 대해 사용자 정의 해시 함수와 동등성 비교 관계를 표현하기 위한 표준 인터페이스입니다. 이는 map[K]V에서 사용하는 컴파일러 정의 기본 방식과 다를 수 있으며, 키 타입이 비교 불가능할 때(예: 슬라이스나 맵) 또는 기본 비교가 잘못된 결과를 낼 때(예: 깊은 비교 연산이 필요한 types.Type 값) 유용합니다. 이 패키지 문서에는 이를 블룸 필터(Bloom filter)에 사용하는 예제가 포함되어 있습니다.
#69559, CL 612217: container/hash.Map[K,V]: 위에서 언급한 사용자 정의 해시 함수를 사용하는 해시 기반 맵입니다.
#80584, CL 741160: container/hash.Set[T]: 동일한 방식의 해시 기반 세트입니다.
#69230, CL 745441: container/set.Set[T]: 요소가 비교 가능한 세트를 위한 공식적인(canonical) 데이터 타입입니다. 이는 map[T]struct{}로 투명하게 표현되며 합집합(Union) 및 교집합(Intersection)과 같은 모든 일반적인 세트 연산을 지원합니다. map[T]bool 및 map[T]struct{}를 기반으로 한 "기존" 세트보다 사용하기 편리하며, map[T]bool에서 발생할 수 있는 false 값에 대한 모호성을 방지합니다. 향후 대부분의 새로운 Go API에서 표준 세트 역할을 할 것으로 기대됩니다.
#77052, CL 724420: container/mapset: API를 변경할 수 없는 기존 코드에서 기존 방식의 세트를 편리하게 다루기 위한 헬퍼 함수(합집합, 교집합 등) 패키지입니다. 이러한 함수들은 set.Set의 메서드와 완전히 동일하게 작동합니다.
#60630: container/ordered.Map[K,V]: 순서가 있는 맵입니다. 현재 구현은 균형 이진 트리를 사용하지만, 설계상 이에 국한되지는 않습니다. 일반적인 Go 패턴인 map[K]V를 만들고 키를 정렬하는 방식은 대부분의 경우 잘 작동하지만, 범위 쿼리(Range query)가 필요한 경우와 같이 때로는 다른 데이터 구조가 훨씬 더 나은 성능을 발휘합니다.
#77397: container/heap/v2.Heap: 표준 라이브러리의 기존 힙을 대체하기 위한 제네릭 이진 힙 API입니다.