목차
Map 정의
Map 생성법1 - var 키워드와 := 기호 이용
Map 생성법2 - make() 함수 이용
빈 Map 생성
허용된 Key 타입
허용된 Value 타입
Map 요소 접근
Map 요소 수정/추가
Map 요소 제거 - delete() 함수
Map 지정 요소 존재 체크
Map 본질 - 해시 테이블 참조
Map 반복
Map 지정 순서대로 반복
Map 정의
key : value 쌍 으로 여러 데이터 값을 저장하는 데이터집합.
맵의 각 요소는 key :value 쌍임.
맵은 (중복 허용 X, 정렬 X, 변경 가능 O )
맵 길이 (= 요소 개수)는 len() 함수로 확인 가능.
맵 기본값: nil (※ null과 같은 개념)
맵은 기본 해시 테이블에 대한 참조를 보유.
맵 정의 순서와 실제 맵 데이터 저장 순서는 다름 . (아래 예제 참고)
Go에는 여러가지 맵 생성법 존재.
Map 생성법1 - var 키워드와 := 기호 이용
[구문]
var a = map[KeyType ]ValueType {key1 :value1 , key2 :value2 ,...}
b := map[KeyType ]ValueType {key1 :value1 , key2 :value2 ,...}
[예제]
package main
import ("fmt")
func main() {
var hz1 = map[string]string{"site":"홈짱닷컴", "host":"홈짱닷컴", "open":"2012"}
hz2 := map[string]int{"HTML": 1, "CSS": 2, "JS": 3, "GO": 4}
fmt.Printf("hz1\t%v\n", hz1)
fmt.Printf("hz2\t%v\n", hz2)
}
결과값:
hz1 map[host:홈짱닷컴 open:2012 site:홈짱닷컴]
hz2 map[CSS:2 GO:4 HTML:1 JS:3]
PS. 주의사항
코드에 정의된 맵 요소 순서는 저장 방식과 다름.
즉, 맵 데이터는 효율적인 검색 방식으로 저장됨.
Map 생성법2 - make() 함수 이용
[구문]
var a = make(map[KeyType ]ValueType )
b := make(map[KeyType ]ValueType )
[예제]
package main
import ("fmt")
func main() {
var hz1 = make(map[string]string)
hz1["site"] = "홈짱닷컴"
hz1["host"] = "Homzzang.com"
hz1["open"] = "2012"
hz2 := make(map[string]int)
hz2["HTML"] = 1
hz2["CSS"] = 2
hz2["JS"] = 3
hz2["GO"] = 4
fmt.Printf("hz1\t%v\n", hz1)
fmt.Printf("hz2\t%v\n", hz2)
}
결과값:
hz1 map[host:Homzzang.com open:2012 site:홈짱닷컴]
hz2 map[CSS:2 GO:4 HTML:1 JS:3]
빈 Map 생성
※ 2가지 방법으로 빈 Map 생성 가능.
make(map[ KeyType ] ValueType ) 함수 사용 (★ 올바른 방법)
var MapName map[KeyType ]ValueType 구문 이용
PS. 주의
2번째 방법으로 빈 Map 생성 후 맵 추가 시, 런타임 패닉 발생. (예제3)
[예제1] - 두 방법으로 Map 생성 시, 각각의 기본 상태 확인
package main
import ("fmt")
func main() {
var a = make(map[string]string)
var b map[string]string
fmt.Println(a == nil) // false
fmt.Println(b == nil) // true
}
[예제2] - make() 방식으로 Map 생성 후, 맵 요소 추가
※ 에러 발생 X
package main
import ("fmt")
func main() {
var a = make(map[string]string)
a["site"] = "홈짱닷컴"
a["host"] = "Homzzang.com"
fmt.Println(a) // map[host:Homzzang.com site:홈짱닷컴]
}
[예제3] - var b map[string]string 방법으로 Map 생성 후, 맵 요소 추가
※ 에러 발생 O
package main
import ("fmt")
func main() {
var b map[string]string
b["site"] = "홈짱닷컴"
b["host"] = "Homzzang.com"
fmt.Println(b) // 에러 발생
}
결과값:
panic: assignment to entry in nil map
goroutine 1 [running]:
main.main()
C:/Users/사용자명/OneDrive/바탕 화면/go/homzzang.go:6 +0x32
exit status 2
허용된 Key 타입
1. 허용 맵 key 유형
∵ 등호연산자( ==) 사용 가능.
Booleans (참거짓)
Numbers (숫자)
Strings (문자열)
Arrays (배열)
Pointers (포인터)
Structs (구조체)
Interfaces (인터페이스) (※ 동적 유형이 동등성을 지원하는 한)
2. 비허용 맵 key 유형
∵ 등호연산자( ==) 사용 불가.
Slices (슬라이스)
Maps (맵)
Functions (함수)
허용된 Value 타입
맵 value(값)은 어떤 자료형이든 가능.
Map 요소 접근
※ 맵 이름과 key 를 이용해 맵의 지정 key 와 연결된 value 에 접근 가능.
map_name [ key ]
[예제]
package main
import ("fmt")
func main() {
var hz = make(map[string]string)
hz["site"] = "홈짱닷컴"
hz["host"] = "Homzzang.com"
hz["open"] = "2012"
fmt.Println(hz["site"] , hz["host"] ) // 홈짱닷컴 Homzzang.com
}
Map 요소 수정/추가
map_name [key ] = value
[주의] Map 요소 수정/추가 시, := 연산자 대신 = 연산자 사용.
[예제]
package main
import ("fmt")
func main() {
var hz = make(map[string]string)
hz["site"] = "홈짱닷컴"
hz["host"] = "Homzzang.com"
hz["open"] = "2012"
fmt.Println(hz["site"], hz["host"]) // 홈짱닷컴 Homzzang.com
hz["site"] = "홈짱"
hz["host"] = "homzzang.com"
fmt.Println(hz) // map[host:homzzang.com open:2012 site:홈짱]
}
Map 요소 제거 - delete() 함수
delete(map_name , key )
[예제]
package main
import ("fmt")
func main() {
var hz = make(map[string]string)
hz["site"] = "홈짱닷컴"
hz["host"] = "Homzzang.com"
hz["open"] = "2012"
fmt.Println(hz) // map[host:Homzzang.com open:2012 site:홈짱닷컴]
delete(hz,"open")
fmt.Println(hz) // map[host:Homzzang.com site:홈짱닷컴]
}
Map 지정 요소 존재 체크
val , ok :=map_name [key ]
val
value (값)
※ 만약, key 가 존재 안 할 시, 값 자료형의 기본값 할당.
ok
key 존재 여부 (true/false 중 하나)
PS1. 특정 key 존재 여부만 확인하려면 val 대신 빈 식별자( _ ) 사용.
PS2. 존재 여부 체크 위해 코드 작성 시, 반드시 사용해야 에러 발생 X
[예제1]
package main
import ("fmt")
func main() {
var a = map[string]string{"site": "홈짱닷컴", "host": "Homzzang.com", "open": "2012", "intro":""}
val1, ok1 := a["site"] // 존재하는 key와 그 value 체크
val2, ok2 := a["visit"] // 존재 않는 key와 그 value 체크
val3, ok3 := a["intro"] // 존재하는 key와 그 value 체크
_ , ok4 := a["host"] // 존재하는 key만 체크 (※ value는 체크 X)
fmt.Println(val1, ok1) // 홈짱닷컴 true
fmt.Println(val2, ok2) // false (∵ key 없어서, value는 빈 문자열)
fmt.Println(val3, ok3) // true (∵ key 있으나, value가 빈 문자열)
fmt.Println(ok4) // true (∵ key 존재만 체크하고, 값은 체크 안 함)
}
결과값:
홈짱닷컴 true
false
true
true
[예제2] - 존재 여부 체크 위해 코드 선언 시, 반드시 사용해야 에러 발생 X
package main
import ("fmt")
func main() {
var a = map[string]string{"site": "홈짱닷컴", "host": "Homzzang.com", "open": "2012", "intro":""}
val1, ok1 := a["site"]
val2, ok2 := a["visit"]
val3, ok3 := a["intro"]
_, ok4 := a["host"]
fmt.Println(val1, ok1)
}
결과값:
# command-line-arguments
.\homzzang.go:11:2: val2 declared but not used
.\homzzang.go:11:8: ok2 declared but not used
.\homzzang.go:12:2: val3 declared but not used
.\homzzang.go:12:8: ok3 declared but not used
.\homzzang.go:13:5: ok4 declared but not used
Map 본질 - 해시 테이블 참조
맵은 해시 테이블에 대한 참조임.
즉,
두 개의 맵 변수가 동일한 해시 테이블 참조 시, 한 변수의 내용 변경 시 다른 변수 내용에 영향 줌.
[예제]
package main
import ("fmt")
func main() {
var hz = map[string]string{"site": "홈짱닷컴", "host": "Homzzang.com", "open": "2012"}
my := hz
fmt.Println("my 맵 수정 전")
fmt.Println(hz)
fmt.Println(my)
my["open"] = ""
fmt.Println("my 맵 수정 후")
fmt.Println(hz)
fmt.Println(my)
}
결과값:
my 맵 수정 전
map[host:Homzzang.com open:2012 site:홈짱닷컴]
map[host:Homzzang.com open:2012 site:홈짱닷컴]
my 맵 수정 후
map[host:Homzzang.com open: site:홈짱닷컴]
map[host:Homzzang.com open: site:홈짱닷컴]
Map 반복
range 키워드 사용한 for 반복문 통해서 Map 반복 실행 가능.
PS. 예전엔 정의된 순서와 달랐으나, 최근엔 Map 정의된 순서대로 출력.
[예제]
package main
import ("fmt")
func main() {
a := map[string]int{"one": 1, "two": 2, "three": 3, "four": 4}
for k, v := range a {
fmt.Printf("%v : %v, ", k, v)
}
}
Go 예전 버전 결과값: two : 2, three : 3, four : 4, one : 1,
Go 최신 버전 결과값: one : 1, two : 2, three : 3, four : 4,
Map 지정 순서대로 반복
순서 정의용 빈 Map 생성 후, 그 안에 원하는 순서대로 key 지정.
[예제]
package main
import ("fmt")
func main() {
a := map[string]int{"one": 1, "two": 2, "three": 3, "four": 4}
fmt.Println("순서 정의 전")
// 순서 없이 반복
for k, v := range a {
fmt.Printf("%v : %v, ", k, v)
}
fmt.Println("\n\n순서 정의 후")
// 순서 정의 ★
var b []string
b = append(b , "four", "three", "two", "one")
// 지정 순서대로 반복
for _, bv := range b {
fmt.Printf("%v : %v, ", bv , a[ bv ])
}
}
결과값:
순서 정의 전
one : 1, two : 2, three : 3, four : 4,
순서 정의 후
one : 1, two : 2, three : 3, four : 4,
[주의] Map 순서 재정의 시, := 연산자가 아닌 = 연산자 사용.
주소 복사
랜덤 이동
최신댓글