• Q&A
  • 회원가입
  • 로그인

GO - Maps (고랭 맵)

88  
목차
  1. Map 정의
  2. Map 생성법1 - var 키워드와 := 기호 이용
  3. Map 생성법2 - make() 함수 이용
  4. 빈 Map 생성
  5. 허용된 Key 타입
  6. 허용된 Value 타입
  7. Map 요소 접근
  8. Map 요소 수정/추가
  9. Map 요소 제거 - delete() 함수
  10. Map 지정 요소 존재 체크
  11. Map 본질 - 해시 테이블 참조
  12. Map 반복
  13. 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 생성 가능.

 

  1. make(map[KeyType]ValueType) 함수 사용 (★ 올바른 방법)
  2. 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 순서 재정의 시, := 연산자가 아닌 = 연산자 사용.



찾아주셔서 감사합니다. Since 2012