Go에서 Set 구현하는 방법: 실전 가이드
Olivia Novak
Dev Intern · Leapcell

Key Takeaways
- Go에는 내장된
Set
유형이 없지만 맵은 효율적인 대안을 제공합니다. struct{}
를 맵 값으로 사용하면 메모리 사용량이 최적화됩니다.golang-set
과 같은 타사 라이브러리는 고급 집합 연산을 제공합니다.
Go에는 다른 프로그래밍 언어에서 볼 수 있는 기본 제공 Set
데이터 구조가 없습니다. 그러나 Go의 맵 유형은 집합의 각 요소가 고유하도록 맵 키의 고유성을 활용하여 집합을 구현하는 편리한 방법을 제공합니다.
맵을 사용하여 집합 구현
Go에서 집합을 만드는 일반적인 방법은 집합 요소를 나타내는 키와 빈 구조체 값을 사용하여 맵을 사용하는 것입니다. 빈 구조체(struct{}
)는 0바이트의 저장 공간을 차지하므로 효율적인 선택이기 때문에 선호됩니다. 다음은 이러한 집합을 정의하고 사용하는 방법에 대한 예입니다.
package main import "fmt" // Set은 고유한 요소의 컬렉션을 나타냅니다. type Set struct { m map[interface{}]struct{} } // NewSet은 주어진 요소로 새 집합을 초기화합니다. func NewSet(items ...interface{}) *Set { s := &Set{ m: make(map[interface{}]struct{}), } s.Add(items...) return s } // Add는 집합에 요소를 삽입합니다. func (s *Set) Add(items ...interface{}) { for _, item := range items { s.m[item] = struct{}{} } } // Remove는 집합에서 요소를 삭제합니다. func (s *Set) Remove(item interface{}) { delete(s.m, item) } // Contains는 요소가 집합에 있는지 확인합니다. func (s *Set) Contains(item interface{}) bool { _, exists := s.m[item] return exists } // Size는 집합의 요소 수를 반환합니다. func (s *Set) Size() int { return len(s.m) } // Clear는 집합에서 모든 요소를 제거합니다. func (s *Set) Clear() { s.m = make(map[interface{}]struct{}) } // Elements는 집합의 모든 요소의 슬라이스를 반환합니다. func (s *Set) Elements() []interface{} { elements := make([]interface{}, 0, len(s.m)) for key := range s.m { elements = append(elements, key) } return elements } func main() { s := NewSet(1, 2, 3, "four") s.Add(5) s.Remove(2) fmt.Println(s.Contains(3)) // Output: true fmt.Println(s.Size()) // Output: 4 fmt.Println(s.Elements()) // Output: [1 3 four 5] s.Clear() fmt.Println(s.Size()) // Output: 0 }
이 구현에서:
NewSet
은 집합을 초기화하고 제공된 요소를 추가합니다.Add
는 새 요소를 집합에 삽입합니다.Remove
는 집합에서 요소를 삭제합니다.Contains
는 요소의 존재를 확인합니다.Size
는 요소 수를 반환합니다.Clear
는 모든 요소를 제거합니다.Elements
는 모든 요소를 슬라이스로 검색합니다.
이 구조는 각 요소가 고유하고 요소를 추가, 제거 및 확인하기 위한 효율적인 작업을 제공합니다.
타사 라이브러리 사용
더욱 고급 집합 연산 및 기능을 위해 golang-set
과 같은 타사 라이브러리를 사용하는 것이 좋습니다. 이 라이브러리는 스레드 안전 및 비 스레드 안전 구현을 포함하여 다양한 기능 세트를 제공하며, 합집합, 교집합 및 차집합과 같은 다양한 집합 연산을 지원합니다.
golang-set
을 사용하려면 먼저 설치하십시오.
go get github.com/deckarep/golang-set/v2
다음은 사용 방법의 예입니다.
package main import ( "fmt" mapset "github.com/deckarep/golang-set/v2" ) func main() { s := mapset.NewSet[int]() s.Add(1, 2, 3) s.Remove(2) fmt.Println(s.Contains(3)) // Output: true fmt.Println(s.Cardinality()) // Output: 2 fmt.Println(s.ToSlice()) // Output: [1 3] }
이 예에서 golang-set
은 Add
, Remove
, Contains
, Cardinality
(요소 수를 가져오는 방법) 및 ToSlice
(모든 요소를 슬라이스로 검색하는 방법)와 같은 메서드를 사용하여 일반 집합 구현을 제공합니다.
성능 고려 사항
맵을 사용하여 집합을 구현할 때 맵의 값 유형을 선택하면 성능에 영향을 줄 수 있습니다. 빈 구조체(struct{}
)를 값 유형으로 사용하는 것이 일반적으로 권장됩니다. 추가 메모리를 소비하지 않기 때문입니다. 벤치마크 테스트 결과, struct{}
값을 가진 맵이 bool
또는 int
와 같은 다른 유형보다 메모리 효율성이 더 높을 수 있습니다.
요약하자면, Go에는 기본 제공 집합 유형이 없지만, 맵 유형을 사용하면 사용자 정의 구현을 통하거나 타사 라이브러리를 활용하여 집합 기능을 효율적이고 유연하게 구현할 수 있습니다.
FAQs
Go의 철학은 단순성을 선호하며 맵 유형은 집합 연산을 효과적으로 지원합니다.
struct{}
는 0바이트를 소비하므로 메모리 효율성이 더 높습니다.
합집합, 교집합 또는 스레드 안전과 같은 고급 기능이 필요한 경우 라이브러리가 유용합니다.
Leapcell은 Go 프로젝트 호스팅을 위한 최고의 선택입니다.
Leapcell은 웹 호스팅, 비동기 작업 및 Redis를 위한 차세대 서버리스 플랫폼입니다.
다중 언어 지원
- Node.js, Python, Go 또는 Rust로 개발하십시오.
무료로 무제한 프로젝트 배포
- 사용량에 대해서만 지불하십시오. 요청이나 요금이 없습니다.
탁월한 비용 효율성
- 유휴 요금 없이 종량제로 지불하십시오.
- 예: $25는 평균 응답 시간 60ms에서 694만 건의 요청을 지원합니다.
간소화된 개발자 경험
- 손쉬운 설정을 위한 직관적인 UI.
- 완전 자동화된 CI/CD 파이프라인 및 GitOps 통합.
- 실행 가능한 통찰력을 위한 실시간 메트릭 및 로깅.
손쉬운 확장성 및 고성능
- 고도의 동시성을 쉽게 처리하기 위한 자동 확장.
- 운영 오버헤드가 없으므로 구축에만 집중하십시오.
설명서에서 자세히 알아보십시오!
X에서 팔로우하세요: @LeapcellHQ