map
Go에서 기본으로 제공하는 map은 Hash Map 구조를 가진다.
// map[키]값
dict := map[int]string{
1: "one",
2: "two",
}
dict[3] = "three"
{중괄호} 안에서 초기화하거나 키를 이용해 값을 삽입할 수 있다.
dict := map[int]string{
1: "one",
2: "two",
}
val, exist := dict[5]
if !exist {
fmt.Println("dict[5] doesn't exist")
} else {
fmt.Println(val)
} // dict[5] doesn't exist
키로 값을 가져올 때, 값과 존재 여부를 반환한다.
for key, value := range dict {
fmt.Printf("%d: %s\n", key, value)
}
range를 통해 map을 (k, v) 형태로 순회할 수 있다. 이때 hash map은 순서를 보장하지 않는다는 점을 주의해야 한다.
container
go 표준 패키지 중 하나로 container를 제공한다.
API 문서: https://pkg.go.dev/container@go1.19.3
- list: 양방향 연결 리스트
- ring: 환형 연결 리스트
- heap: 힙
List:
package main
import (
"container/list"
"fmt"
)
func main() {
l := list.New()
eLast := l.PushBack("z")
eHead := l.PushFront("a")
eTwo := l.InsertAfter(2, eHead)
l.Remove(eTwo)
l.InsertAfter(1, eHead)
l.InsertBefore(9, eLast)
fmt.Printf("Len: %d\n", l.Len())
for e := l.Front(); e != nil; e = e.Next() {
fmt.Print(e.Value)
}
}
/*
* Len: 4
* a19z
*/
예시로 든 list는 {앞 요소, 뒷 요소, 값}을 가진 객체이다. 따라서 메모리에 독립적으로 저장된 객체들을 연결시킬 수 있다. list를 활용하면 Queue, Stack과 같은 자료 구조로 확장할 수 있다.
Queue:
type Queue struct {
List *list.List
}
func NewQueue() *Queue {
queue := Queue{list.New()}
return &queue
}
func (q *Queue) Push(n int) {
q.List.PushBack(n)
}
func (q *Queue) Pop() interface{} {
val := q.List.Front()
if val != nil {
return q.List.Remove(val)
}
return nil
}
func main() {
queue := NewQueue()
for i := 1; i < 10; i++ {
queue.Push(i)
}
for {
val := queue.Pop()
if val == nil {
return
}
fmt.Printf("%d-", val)
}
} // 1-2-3-4-5-6-7-8-9-
Stack:
type Stack struct {
List *list.List
}
func NewStack() *Stack {
stack := Stack{list.New()}
return &stack
}
func (q *Stack) Push(n int) {
q.List.PushBack(n)
}
func (q *Stack) Pop() interface{} {
val := q.List.Back()
if val != nil {
return q.List.Remove(val)
}
return nil
}
func main() {
stack := NewStack()
for i := 1; i < 10; i++ {
stack.Push(i)
}
for {
val := stack.Pop()
if val == nil {
return
}
fmt.Printf("%d-", val)
}
} // 9-8-7-6-5-4-3-2-1-