코드를 짜던 중 json ↔ []string 변환 사이에서 Marshal, Unmarshal 함수 호출을 했는데, 쓰면서도 계속 두 가지가 헷갈려서 정리를 하게 되었다. 그리고, map[string], interface에 대해서도 한 번 더 짚고 넘어 가려고 한다.
표준 패키지인 encoding/json을 사용하면 된다. 참고로 미리 언급하자면, Marshal을 통해 맵을 JSON문서로 변환 가능하다.
일반적으로 Go에서 map[string] interface{}를 쓰는 이유는 JSON데이터를 다루기 위함이다. 즉, 문자열 키와 임의의 인터페이스 값을 매핑하는 map으로, 동적으로 key-value 쌍을 저장 가능하다.
Go에서 특정 데이터를 Dictionary로 보관하기 위해선, Key-Value가 어떤 자료형인지 명시해주어야 하므로!!
여러 개의 map[string] interface{}를 가질려면 []map]string]interface{}를 사용하면 된다.
빈 맵 생성을 위해 make함수를 사용할 수도 있다. (맵으로 초기화)
m := make(map[string]interface{})
m["name"] = "Dusdj"
m["age"] = 23
m["Active"] = true
1. Marshal : golang obejct (string, struct) → []byte, string로 변환
2. Unmarshal : []byte, string → golang object
(JSON 포맷으로 인코딩)
func Marshal(v interface{}) ([]byte, error)
ex)
package main
import (
"encoding/json"
"fmt"
)
type Member struct {
Name string
Age int
Active bool
)
func main() {
mem := Member{"Dusdj", 23, true}
//JSON 인코딩
jsonBytes, err := json.Marshal(mem)
if err != nil {
panic(err)
}
//JSON 바이트를 문자열로 변경
jsonString := string(jsonBytes)
fmt.Println(jsonString)
}
디코딩
func Unmarshal(data []byte, v interface{}) error
func main() {
jsonBytes, _ := json.Marshal(Member{"Dusdj", 23, true})
//JSON 디코딩
var mem Member
err := json.Unmarshal(jsonBytes, &mem)
if err != nil {
panic(err)
}
fmt.Println(mem.Name, mem.Age, mem.Active)
}
NewDecoder랑 Marshalling이랑 헷갈릴 수도 있을 것 같다.
NewDecoder
Marshal
var v map[string]interface{}
data := ioutil.ReadAll(r.Body)
json.Unmarshal(data, &v) //두번째 인자 : 변수(포인터 값)