Go 1.28 제네릭 컬렉션 타입 제안
Go는 Go 1.28에서 포괄적인 제네릭 컬렉션 타입 세트를 도입하여 이전에 누락되었거나 우회 구현으로만 존재하던 표준적이고 ergonomic한 데이터 구조를 제공합니다. 이 이동은 Go 1.18의 제네릭 추가와 Go 1.23의 이터레이터를 활용하여 Go의 핵심 원칙인 실용성과 단순성을 유지하면서 일반적인 데이터 구조를 표준 라이브러리로 가져옵니다.
새로운 표준 컬렉션 타입
Go 컬렉션 작업 그룹은 세트, 맵, 힙을 처리하는 방법을 표준화하기 위해 여러 새로운 패키지와 타입을 제안합니다.
해시 기반 컬렉션
container/hash.Map[K, V]:hash/maphash.Hasher인터페이스를 통해 사용자 정의 해시 함수와 동등 관계를 지원하는 해시 기반 맵입니다. 이는 비교할 수 없는 키 타입(예: 슬라이스 또는 맵)이나 깊은 비교가 필요한 경우에 특히 유용합니다.container/hash.Set[T]:container/hash.Map과 동일한 사용자 정의 해시 원칙을 따르는 해시 기반 세트 구현입니다.container/set.Set[T]: 비교 가능한 요소에 대한 표준 세트로, 내부적으로map[T]struct{}로 투명하게 표현됩니다. Union과 Intersection과 같은 표준 세트 연산을 제공하며, 레거시map[T]bool또는map[T]struct{}패턴을 대체하기 위해 설계되었습니다.
순서가 있고 특수한 컬렉션
container/ordered.Map[K, V]: 범위 쿼리가 필요한 사용 사례를 위해 설계된 순서가 있는 매핑 구현(현재 균형 이진 트리를 사용)으로, map 키를 수동으로 정렬하는 일반적인 패턴보다 성능이 뛰어납니다.container/heap/v2.Heap: 기존container/heap구현을 대체하기 위해 설계된 제네릭 바이너리 힙 API로, 기존 구현은 사용하기 어렵다는 평가가 널리 퍼져 있습니다.
헬퍼 패키지
container/mapset: 기존 코드에 API 변경을 요구하지 않고 "레거시" 세트(기존map[T]struct{}코드)를 조작하기 위한 헬퍼 함수(Union, Intersection 등)의 모음입니다.
추상 컬렉션 제약 조건
다양한 컬렉션 구현 간의 일관성을 보장하기 위해 Go 팀은 내보내지 않은 추상 제약 인터페이스를 도입했습니다. 이러한 인터페이스는 F-바운드 다형성(재귀적 제약 인터페이스)을 사용하여 Union(S) S와 같은 메서드가 피연산자와 결과에 동일한 구체적인 세트 타입을 사용하도록 보장함으로써 "바이너리 메서드 문제"를 해결합니다.
내부 계층 구조는 다음과 같습니다:
_AbstractCollection[E, C]:Clear(),Clone(),Contains(E),Len()과 같은 기본 작업을 정의합니다._AbstractMap[K, V, M]: 컬렉션 인터페이스를 확장하여Get(K),Set(K, V),Keys()와 같은 맵별 작업을 추가합니다._AbstractSet[E, S]: 컬렉션 인터페이스를 확장하여Union(S),Intersection(S),SymmetricDifference(S)와 같은 세트별 작업을 추가합니다.
이러한 인터페이스는 현재 내보내지지 않아 Go 팀이 공개 API에 확정하기 전에 실무에서 배울 수 있도록 하지만, 표준 라이브러리 전반에 걸쳐 일관성을 위한 청사진 역할을 합니다.
설계 근거 및 API 관례
새로운 컬렉션 API는 성능과 인간공학을 최적화하기 위해 몇 가지 특정 설계 선택을 따릅니다:
- 정보가 풍부한 반환 값: 변형 메서드는 컬렉션 크기의 변화를 보고합니다.
Map.Set과Map.Delete는 이전 값과 불리언을 반환하여 기존 키와 제로 값을 구분합니다. - -With 변형: 세트 대수 연산은 두 가지 형태로 제공됩니다: 순수 함수형 버전(예:
Union)은 새로운 세트를 반환하고, 변형 버전(예:UnionWith)은 왼쪽 피연산자를 수정하여 불필요한 할당을 피합니다. - 점근적 성능: 트리 기반 맵과 같은 특수 구현이 일반적인 루프 기반 구현보다 점근적으로 더 효율적인(O(n) vs O(n log n)) 경우,
DeleteFunc와 같은 특정 작업은 인터페이스에 유지됩니다.
커뮤니티 관점
제안에 대한 커뮤니티 반응은 혼합되어 있으며, Go의 발전에 대한 오랜 논쟁을 반영합니다.
일부 개발자는 이러한 추가가 오래 기다려온 현대화라고 봅니다:
"세트나 타입이 지정된 힙 같은 것은 오래전부터 필요했습니다."
다른 이들은 언어가 이러한 기능을 천천히 채택하는 것이 산업 표준에 늦게 합류하는 패턴을 반영한다고 주장합니다:
"단계별로, Go는 지난 20년 동안 다른 언어들이 배운 힘든 교훈을 이제 배우고 있습니다."
또한 일부 커뮤니티는 제네릭과 복잡한 컬렉션 타입의 추가가 Go의 원래 정체성인 "빈곤한 프로그래머를 위한 단순함"에서 멀어지게 하여 평균 개발자에게 언어를 더 복잡하게 만들고 라이브러리 저자에게만 이익을 준다고 우려합니다.