일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 개발 공식문서 읽기
- 개발실무
- postgredb
- 코멘토실무PT
- 개발 영어실력
- 데이터베이스
- Go언어
- golang
- 스키마모델
- HTTP
- 웹서버
- 개발 공식문서
- 코딩강의
- 유데미
- 자료구조
- 개발공식문서 어려움
- 리액트
- 데이터스키마
- 개발자되기
- 알고리즘
- tableplus
- 실무PT
- 자바
- 파이썬
- Go언어실무
- 개발자공통지식
- 컴공과개념정리
- 개발공부
- jsx
- 코멘토
- Today
- Total
웹개발일지
Go 자료구조 : map [맵] 본문
이 글은 아래 링크 자료를 참고 및 번역하여 Go의 맵 자료형에 대해 조사한 내용입니다.
https://articles.wesionary.team/map-types-in-golang-24591abbafc6
map Types in Golang
What is actually a map in Golang?.
articles.wesionary.team
맵 자료형
Go의 맵은 특정 데이터 타입을 지칭한다기 보다, 다른 데이터 타입들을 'key'와 'value'로서 사용하기위해 만들어 쓴다.
기본형태
TYPE{
KEY: VALUE,
...
}
맵의 기본 형태이다.
map[string]int
map[string]int는 string을 key로 사용하고 int를 value로 사용하겠다는 정의이다.
key 와 value 타입에 어떤것을 사용하느냐
맵을 정의할 때 슬라이스와 함수를 사용할 수 있을까? 정답은 아니오다. 왜냐, 키는 무조건 비교 연산이 가능한 타입이어야 하는 것인데, Go의 기본 자료형인 string, int와 같은 것을 제외하고는 비교 연산이 불가하다. 그렇기 때문이 func와 slice는 맵의 키로 사용할수가 없다. 같은 이유로 맵의 키로서 맵을 사용할 수 없다.
하지만 맵의 value에는 제한이 없다. 그 어떠한 타입도 올 수 있다. 만약, 값으로 아무것도 넣지 않는다면 비어있는 맵 자료형으로 초기화 하게 되는 것이다. 표현식은 아래와 같다.
var menuprice map[string]int{}
이를 사용은 가능하다. 하지만 nil값을 읽거나 쓸수는 없다.
그렇다면 맵을 어떻게 저장하고 사용할까?
1. 맵에 특정 키값이 존재하는지 확인하자
menuprice, ok := menu["cheeseburger"]
if ok {
return fmt.Sprintf("Yes, cheeseburger is on the menu;%f", menuprice)
}
return fmt.Sprint("no any cheeseburger!")
여기서 키 값이 매칭된다면 ok값으로 true가 반환될 것이다. 그렇지 않으면 false가 반환될 것이다. 반환 값의 첫번째 인자로 받을 것 이 없다면 menuprice를 선언하는 것 대신 _ (언더바 기호)를 붙여 '_, ok :='로 생략하여 선언할 수 있다.
2. 불리언 형태의 맵을 값으로
우리가 현재 가진 재료들의 재고를 표현한 inStock 이라는 맵을 예시로 보자.
var inStock = map[string]bool {
"eggs": true,
"buffsausage": true,
"chickensausage": true,
}
특정 item을 인자로 받아 그것이 inStock에 있는지 어떻게 확인할 수 있을까? value('_'로 표현)와 ok 를 결괏값으로 확인하면 된다. 주어진 인자를 key값으로 맵에 조회하여 해당 key가 존재하는지 검사하면 value와 그 결과를 ok를 통해 알 수 있다. 만약 false를 결과로 갖는다면 출력값으로 메시지와 함께 인자로 넣었던 key name을 다시 반환하자.
if _, ok := inStock[eggs]; ok {
return fmt.Sprintf("is in stock", eggs)
}
return fmt.Sprintf("Sorry, out of stock", eggs)
3. 맵을 순회 하는 방법
range 연산자를 사용하여 맵을 순회하고 값을 받아보자. key-value 각각을 읽어 변수값으로 할당받게 된다.
for x, y:= range instock{
fmt.Println(x,y)
}
루프를 돌 때 마다 다음 key값으로 넘어가면서 그 key값에 일치하는 value값을 찾는다.
4. map에 자료 append()하기
var dishes []string
for dish:= range instock{
dishes = append(dishes, dish)
}
fmt.Println(dishes)
sorteddishes:= sort.Strings(dishes)
fmt.Println(sortdishes)
1. string형태 자료들이 담긴 슬라이스 변수 dishes를 선언했다.
2. 맵 자료형 변수 instock을 순회한 값을 dish에 담았다. dish 값은 dishes에 append 로 추가되었다. 빈 문자열 슬라이스에 instock 의 자료들이 하나씩 들어가게된다.
위 출력 결과가 매번 순서가 다르게 나와서 찾아보니 맵은 순서보장이 안된다고 한다. 순서가 보장되는 것을 원한다면 key를 지정해서 사용해야 한다.
5. Go가 자료를 순회하는 방법
Iteration order
When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next. If you require a stable iteration order you must maintain a separate data structure that specifies that order. This example uses a separate sorted slice of keys to print a map[int]string in key order:
import "sort"
var m map[int]string
var keys []int
for k := range m {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
fmt.Println("Key:", k, "Value:", m[k])
}
맵에는 해시 맵과 sorted맵이 있는데 첫번째는 정렬되지 않고 순서가 보장되지 않으며 이것이 Go의 맵이라고 한다. sorted 맵은 키값으로 정렬이 된다. 그러니까 Go의 맵은 내부에서 요소를 보관할 때 입력한 순서와도 키 값과도 상관없이 데이터를 보관하는 원리라고 한다. 맵의 동작을 자세히 이해하려면 해시 함수의 동작을 이해해야한다고 한다.
6. map[string]interface{}
interface{} 가 무엇일까? 어떠한 메소드도 갖지 않는다. 하지만 그것이 빈 인터페이스가 어떤 메서드도 가져선 안된다는 걸 말하는 게 아니다! 빈 인터페이스는 어떠한 값도 받을 수 있다. string, int, struct, pointer와 같은 자료들 말이다.
- examples below
menus := map[string]interface{}{
"icecream": "delicious",
"eggs": struct {
price float64
}{"chicken", 1.75},
"chickenSteak": true,
}
type Person struct {
Name string
Age int
Hobbies []string
}
person:=map[string]interface{
"name":"John",
"age":29,
"hobbies":[
"martial arts",
"breakfast foods",
"piano"
]
}
7. 언제 map[string]interface{} 를 사용할까?
위 타입은 우리가 데이터를 다룰 때 매우 유용하게 쓰인다. 마치 여러 자료형태가 뒤섞인 JSON 자료형같은 걸 다룰 때 말이다.
이렇게 Go언어의 맵 자료형에 대해 조사하고 기초 예제를 복습해보았다. 처음 입문서로 배울 땐 막연하게 key와 value 데이터로 이루어진 자료구조라는 것 정도로만 이해하고 있었는데 유용하게 쓰이는 것 같다. 알고리즘 문제풀이를 하면서 맵의 동작원리에 대해 더 공부해보도록 해야겠다.
'Lang > Go' 카테고리의 다른 글
Go언어의 동시성 프로그래밍, 고루틴 (0) | 2023.08.29 |
---|---|
CRUD 게시판 웹서버 구현 (0) | 2023.01.06 |
Docker 활용 웹 어플리케이션 배포 (0) | 2023.01.06 |
Go Scan() 함수의 기본과 활용 (0) | 2023.01.05 |
Golang 기본 문법 복습 및 Mutex 패키지 활용 (3) | 2022.12.20 |