# golang container package **Published by:** [Primrose](https://paragraph.com/@primrose/) **Published on:** 2023-06-12 **URL:** https://paragraph.com/@primrose/golang-container-package ## Content container packagegolang에는 빌트인으로 사용할 수 있는 container package가 있다. 개발을 하다보면, 자료구조를 사용할 일이 꽤 생긴다. go에서는 container 패키지에서 기본 자료구조를 제공해주므로 꽤나 편리하게 사용할 수 있다. 패키지에서 제공하는 자료구조는 다음과 같다.Linked listHeapRing (Circular list)container 패키지를 이용해서 간단한 자료구조를 구현해보자.container/listpackage main import ( "container/list" "log" ) func main() { lst := list.New() lst.PushBack(1) lst.PushBack(2) lst.PushBack(3) log.Println(lst.Len()) } 위와 같이 container/list 패키지를 import하면, 손쉽게 linked list를 사용할 수 있다. 개발을 하면서 linked list를 사용해야 한다면, 꽤나 시간을 단축시킬 수 있을 것이다. list를 순회하고 싶다면 아래와 같은 방법도 가능하다.package main import ( "container/list" "fmt" "log" ) func main() { lst := list.New() lst.PushBack(1) lst.PushBack(2) lst.PushBack(3) log.Println(lst.Len()) for e := lst.Front(); e != nil; e = e.Next() { // 연결 리스트의 맨 앞부터 끝까지 순회 fmt.Println(e.Value) } } container/heap다음은 heap 패키지이다. 필자는 최근 회사에서 체결엔진/오더북을 구현하면서 min heap과 max heap을 구현할 일이 있었는데, container/heap 패키지를 통해 간단하게 구현할 수 있었다. heap 패키지에서는 기본적으로 다음과 같은 인터페이스가 필요하다.package heap type Interface interface { Len() int Less(i, j int) bool Swap(i, j int) Push(x any) Pop() any } 한 번 구현해서 사용해보자. 예제에서는 min heap을 구현해본다.package main import ( "container/heap" "log" ) type IMinHeap interface { heap.Interface } type MinHeap struct { heap []uint } func (m *MinHeap) Len() int { return len(m.heap) } func (m *MinHeap) Less(i, j int) bool { return m.heap[i] < m.heap[j] } func (m *MinHeap) Swap(i, j int) { m.heap[i], m.heap[j] = m.heap[j], m.heap[i] } func (m *MinHeap) Push(x any) { m.heap = append(m.heap, x.(uint)) } func (m *MinHeap) Pop() any { old := m.heap n := len(old) element := old[n-1] m.heap = old[0 : n-1] return element } func main() { minHeap := &MinHeap{heap: []uint{}} heap.Init(minHeap) heap.Push(minHeap, uint(10)) heap.Push(minHeap, uint(20)) heap.Push(minHeap, uint(50)) heap.Push(minHeap, uint(5)) log.Println(heap.Pop(minHeap)) // 5 log.Println(heap.Pop(minHeap)) // 10 log.Println(heap.Pop(minHeap)) // 20 log.Println(heap.Pop(minHeap)) // 50 } Less 조건의 부호만 반대로 바꿔줘도 max heap으로 바꾸어 사용할 수 있어 편하다.container/ring다음은 ring이다. ring은 비교적 사용할 일이 많이 없는 듯 보이지만, 알아두면 때때로 도움이 될 수도 있다. 개인적으로는 list를 쓰는 편이긴 하다.package main import ( "container/ring" "fmt" ) func main() { data := []string{"Maria", "John", "Andrew", "James"} r := ring.New(len(data)) // 노드의 개수를 지정하여 링 생성 for i := 0; i < r.Len(); i++ { // 링 노드 개수만큼 반복 r.Value = data[i] // 링의 노드에 값 넣기 r = r.Next() // 다음 노드로 이동 } r.Do(func(x interface{}) { // 링의 모든 노드 순회 fmt.Println(x) }) // "Maria" // "John" // "Andrew" // "James" } 두 개의 ring을 연결하는 것도 물론 가능하다.package main import ( "container/ring" "fmt" ) func main() { data := []string{"Maria", "John", "Andrew", "James"} r := ring.New(len(data)) // 노드의 개수를 지정하여 링 생성 for i := 0; i < r.Len(); i++ { // 링 노드 개수만큼 반복 r.Value = data[i] // 링의 노드에 값 넣기 r = r.Next() // 다음 노드로 이동 } r.Do(func(x interface{}) { // 링의 모든 노드 순회 fmt.Println(x) }) // "Maria" // "John" // "Andrew" // "James" newData := []uint{1, 2, 3, 4} r2 := ring.New(len(newData)) for i := 0; i < r2.Len(); i++ { // 링 노드 개수만큼 반복 r2.Value = newData[i] // 링의 노드에 값 넣기 r2 = r2.Next() // 다음 노드로 이동 } r3 := r.Link(r2) r3.Do(func(x interface{}) { // 링의 모든 노드 순회 fmt.Println(x) }) // John // Andrew // James // Maria // 1 // 2 // 3 // 4 } ## Publication Information - [Primrose](https://paragraph.com/@primrose/): Publication homepage - [All Posts](https://paragraph.com/@primrose/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@primrose): Subscribe to updates