-
[Golang] encoding/json 패키지 알아보기Golang 2024. 6. 12. 07:23728x90반응형
- 목차
들어가며.
Go 의 encoding/json 패키지는 JSON 데이터를 처리할 수 있도록 지원합니다.
본 글에서는 encoding/json 패키지의 주요 기능과 다양한 예제를 통해 심층적으로 다뤄보겠습니다.
Marshal ( struct 를 Json 으로 인코딩 ).
encoding/json 패키지는 Marshal 함수를 제공합니다.
Marshal 이라는 표현인 Encoding 과 유사한 개념으로 이해하시면 되며, Go struct 를 JSON으로 인코딩하는 역할을 수행합니다.
Marshal 함수의 시그니처는 아래와 같습니다.
Marshal 함수는 인자로써 interface{} 타입을 필요로 합니다.
interface{} 타입은 다른 프로그래밍 언어의 Any 나 Object 같이 모든 데이터 타입을 의미하는 Wildcard 로 동작합니다.
( 좀 더 심층적으로 바라보자면 어떠한 Method 도 구현하지 않아도 되는 인터페이스이기 때문에 Wildcard 로 동작됨. )
그리고 인코딩된 결과인 []byte 를 반환합니다.
func Marshal(v interface{}) ([]byte, error)
json.Marshal 함수의 활용 예시는 아래와 같습니다.
package json import ( "encoding/json" "fmt" ) type Person struct { Name string `json:"name"` Age int `json:"age"` } func JsonTestMain() { p := Person{Name: "John Doe", Age: 30} data, err := json.Marshal(p) if err != nil { panic(err) } fmt.Println(string(data)) // {"name":"John Doe","age":30} }
위 예시에서는 Person 이라는 구조체를 json.Marshal 함수를 통해서 인코딩을 적용합니다.
주목할 점은 type Person struct 의 코드 블록 내부에 `json:"name"` 와 같은 태그가 존재합니다.
만약 `json:"name"` 와 같은 태그가 존재하지 않는다면 구조체의 변수 식별자가 그대로 JSON 의 Key 로써 사용됩니다.
Golang 은 구조적으로 외부 패키지에서의 접근을 허용하기 위해서 대분자로 시작하는 식별자를 사용해야합니다.
이러한 구조적인 이유로 인해서 json 태그가 사용됩니다.
구조체 내부에 json Tag 를 사용하지 않는다면 ?
아래의 예시와 같이 type Person struct 코드 블록 내부에서 json Tag 를 사용하지 않는다면,
Person 구조체의 변수 Name 과 Age 가 JSON Key 로써 사용됩니다.
package json import ( "encoding/json" "fmt" ) type Person struct { Name string Age int } func JsonTestMain() { p := Person{Name: "John Doe", Age: 30} data, err := json.Marshal(p) if err != nil { panic(err) } fmt.Println(string(data)) // {"Name":"John Doe","Age":30} }
Unmarshal ( Json 을 struct 로 Decoding ).
json.Unmarshal 함수를 통해서 JSON 을 Golang 구조체로 변환할 수 있습니다.
json.Unmarshal 함수 의 시그니처는 아래와 같습니다.
json.Marshal 과 반대로 []byte Slice 함수의 첫번째 인자로 받습니다.
그리고 두번째 인자로 JSON 데이터를 역직렬화할 대상 객체를 전달합니다.
Deserialization 결과를 반환하는 구조가 아니라 역직렬화할 대상 객체를 필요로 합니다.
func Unmarshal(data []byte, v interface{}) error
아래는 json.Unmarshal 함수의 활용 예시입니다.
name 과 age 로 구성된 JSON 문자열을 var p Person 구조체로 역직렬화합니다.
주목할 점은 &p 와 같이 포인터 형식으로 대상 객체를 전달해야 한다는 점입니다.
package json import ( "encoding/json" "fmt" ) type Person struct { Name string `json:"name"` Age int `json:"age"` } func JsonTestMain() { data := []byte(`{"name": "John", "age": 30}`) var p Person err := json.Unmarshal(data, &p) if err != nil { fmt.Println("Error:", err) return } fmt.Println(p) // {John 30} }
JSON 문자열과 구조체의 형식이 맞지 않을 때.
만약 JSON 문자열과 구조체의 형식이 맞지 않을 때에 어떻게 동작하는지 알아보겠습니다.
구조체에 존재하지 않는 JSON Key 가 있는 경우.
아래의 예시와 같이 struct 의 변수인 name 과 age 이 이외에 city 라는 새로운 JSON Key 가 존재하는 경우에,
구조체에 존재하지 않는 새로운 Key 는 역직렬화 대상에서 제외됩니다.
package json import ( "encoding/json" "fmt" ) type Person struct { Name string `json:"name"` Age int `json:"age"` } func JsonTestMain() { data := []byte(`{"name": "John", "age": 30, "city": "Seoul"}`) var p Person err := json.Unmarshal(data, &p) if err != nil { fmt.Println("Error:", err) return } fmt.Println(p) // {John 30} }
구조체에 존재하는 JSON Key 가 누라된 경우.
아래의 예시와 같이 age 라는 구조체 변수가 JSON 에서 누락된 경우에는 age 가 int Zero Value 인 0 으로 초기하됩니다.
package json import ( "encoding/json" "fmt" ) type Person struct { Name string `json:"name"` Age int `json:"age"` } func JsonTestMain() { data := []byte(`{"name": "John", "city": "Seoul"}`) var p Person err := json.Unmarshal(data, &p) if err != nil { fmt.Println("Error:", err) return } fmt.Println(p) // {John 0} }
JSON 형식이 이상한 경우.
JSON 형식에 문제가 있어서 파싱에 실패하는 경우도 존재합니다.
이 경우에는 error 를 리턴하게 되며, Error Handling 이 필요합니다.
package json import ( "encoding/json" "fmt" ) type Person struct { Name string `json:"name"` Age int `json:"age"` } func JsonTestMain() { data := []byte(`{""name": "John", "city": "Seoul"}`) var p Person err := json.Unmarshal(data, &p) if err != nil { fmt.Println("Error:", err) // Error: invalid character 'n' after object key return } fmt.Println(p) }
반응형'Golang' 카테고리의 다른 글
[Golang] go install 과 go get 의 차이 알아보기 (0) 2024.06.15 [Golang] time 패키지의 기본적인 사용법 알아보기 ( Now, LoadLocation ) (0) 2024.06.12 [Go] regexp 패키지와 정규표현식 알아보기 (0) 2024.06.08 golang package 이해하기 (2) 2023.09.18 golang struct 이해하기 (0) 2023.09.18