수색…
통사론
- func 마샬 (v interface {}) ([] 바이트, 오류)
- func Unmarshal (data [] byte, v interface {}) 오류
비고
"encoding/json"
패키지 인 json 패키지는 Go
에서 JSON 객체의 인코딩과 디코딩을 구현 Go
.
JSON의 해당 유형과 Go의 해당 유형은 다음과 같습니다.
JSON 유형 | 콘크리트 유형 이동 |
---|---|
부울 | 불량배 |
번호 | float64 또는 int |
끈 | 끈 |
없는 | 무 |
기본 JSON 인코딩
"encoding/json"
패키지의 json.Marshal
은 값을 JSON으로 인코딩합니다.
매개 변수는 인코딩 할 값입니다. 반환 값은 JSON 인코딩 된 입력을 나타내는 바이트 배열 (성공시)과 오류 (실패시)입니다.
decodedValue := []string{"foo", "bar"}
// encode the value
data, err := json.Marshal(decodedValue)
// check if the encoding is successful
if err != nil {
panic(err)
}
// print out the JSON-encoded string
// remember that data is a []byte
fmt.Println(string(data))
// "["foo","bar"]"
다음은 내장 데이터 유형에 대한 인코딩의 몇 가지 기본 예제입니다.
var data []byte
data, _ = json.Marshal(1)
fmt.Println(string(data))
// 1
data, _ = json.Marshal("1")
fmt.Println(string(data))
// "1"
data, _ = json.Marshal(true)
fmt.Println(string(data))
// true
data, _ = json.Marshal(map[string]int{"London": 18, "Rome": 30})
fmt.Println(string(data))
// {"London":18,"Rome":30}
간단한 변수 인코딩은 Go에서 JSON 인코딩이 작동하는 방식을 이해하는 데 도움이됩니다. 그러나 현실 세계에서는 구조체에 저장된 더 복잡한 데이터를 인코딩 할 가능성이 높습니다.
기본 JSON 디코딩
json.Unmarshal
패키지 "encoding/json"
은 JSON 값을 주어진 변수가 가리키는 값으로 디코딩합니다.
매개 변수는 []bytes
로 디코딩 할 값이고 비 직렬화 값의 저장소로 사용할 변수입니다. 반환 값은 오류 (실패시)입니다.
encodedValue := []byte(`{"London":18,"Rome":30}`)
// generic storage for the decoded JSON
var data map[string]interface{}
// decode the value into data
// notice that we must pass the pointer to data using &data
err := json.Unmarshal(encodedValue, &data)
// check if the decoding is successful
if err != nil {
panic(err)
}
fmt.Println(data)
map[London:18 Rome:30]
위의 예에서 우리는 키의 유형과 값을 미리 알고 있었음에 유의하십시오. 그러나 이것이 항상 그런 것은 아닙니다. 사실, 대부분의 경우 JSON은 혼합 값 유형을 포함합니다.
encodedValue := []byte(`{"city":"Rome","temperature":30}`)
// generic storage for the decoded JSON
var data map[string]interface{}
// decode the value into data
if err := json.Unmarshal(encodedValue, &data); err != nil {
panic(err)
}
// if you want to use a specific value type, we need to cast it
temp := data["temperature"].(float64)
fmt.Println(temp) // 30
city := data["city"].(string)
fmt.Println(city) // "Rome"
위의 마지막 예제에서 우리는 디코드 된 값을 저장하기 위해 일반 맵을 사용했습니다. 우리는 키가 문자열이라는 것을 알고 있기 때문에 map[string]interface{}
를 사용해야 만합니다. 그러나 우리는 미리 값의 유형을 알지 못합니다.
이는 매우 간단한 접근 방법이지만 매우 제한적입니다. 실제 세상에서는 일반적으로 JSON을 사용자 정의 된 struct
유형 으로 디코딩합니다 .
파일에서 JSON 데이터 디코딩
JSON 데이터는 파일에서 읽을 수도 있습니다.
다음과 같은 내용의 data.json
파일이 있다고 가정 해 보겠습니다.
[
{
"Name" : "John Doe",
"Standard" : 4
},
{
"Name" : "Peter Parker",
"Standard" : 11
},
{
"Name" : "Bilbo Baggins",
"Standard" : 150
}
]
다음 예제에서는 파일을 읽고 내용을 디코딩합니다.
package main
import (
"encoding/json"
"fmt"
"log"
"os"
)
type Student struct {
Name string
Standard int `json:"Standard"`
}
func main() {
// open the file pointer
studentFile, err := os.Open("data.json")
if err != nil {
log.Fatal(err)
}
defer studentFile.Close()
// create a new decoder
var studentDecoder *json.Decoder = json.NewDecoder(studentFile)
if err != nil {
log.Fatal(err)
}
// initialize the storage for the decoded data
var studentList []Student
// decode the data
err = studentDecoder.Decode(&studentList)
if err != nil {
log.Fatal(err)
}
for i, student := range studentList {
fmt.Println("Student", i+1)
fmt.Println("Student name:", student.Name)
fmt.Println("Student standard:", student.Standard)
}
}
data.json
파일은 Go 실행 가능 프로그램의 동일한 디렉토리에 있어야합니다. Go에서 파일 을 사용하는 방법에 대한 자세한 정보는 파일 I / O 문서 를 읽으십시오.
해독을 위해 익명 구조체 사용
익명 구조체를 사용하는 목적은 우리가 신경 쓰는 정보만을 디코딩하는 것입니다. 단 하나의 함수에서만 사용되는 유형으로 응용 프로그램을 낭비하지 않아도됩니다.
jsonBlob := []byte(`
{
"_total": 1,
"_links": {
"self": "https://api.twitch.tv/kraken/channels/foo/subscriptions?direction=ASC&limit=25&offset=0",
"next": "https://api.twitch.tv/kraken/channels/foo/subscriptions?direction=ASC&limit=25&offset=25"
},
"subscriptions": [
{
"created_at": "2011-11-23T02:53:17Z",
"_id": "abcdef0000000000000000000000000000000000",
"_links": {
"self": "https://api.twitch.tv/kraken/channels/foo/subscriptions/bar"
},
"user": {
"display_name": "bar",
"_id": 123456,
"name": "bar",
"staff": false,
"created_at": "2011-06-16T18:23:11Z",
"updated_at": "2014-10-23T02:20:51Z",
"logo": null,
"_links": {
"self": "https://api.twitch.tv/kraken/users/bar"
}
}
}
]
}
`)
var js struct {
Total int `json:"_total"`
Links struct {
Next string `json:"next"`
} `json:"_links"`
Subs []struct {
Created string `json:"created_at"`
User struct {
Name string `json:"name"`
ID int `json:"_id"`
} `json:"user"`
} `json:"subscriptions"`
}
err := json.Unmarshal(jsonBlob, &js)
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%+v", js)
출력 : {Total:1 Links:{Next:https://api.twitch.tv/kraken/channels/foo/subscriptions?direction=ASC&limit=25&offset=25} Subs:[{Created:2011-11-23T02:53:17Z User:{Name:bar ID:123456}}]}
일반적인 경우는 다음을 참조하십시오 : http://stackoverflow.com/documentation/go/994/json/4111/encoding-decoding-go-structs
JSON 구조체 필드 설정하기
다음 예제를 고려하십시오.
type Company struct {
Name string
Location string
}
특정 필드 숨기기 / 건너 뛰기
Revenue
및 Sales
를 내보내고 인코딩 및 디코딩에서 숨기려면 json:"-"
하거나 변수의 이름을 소문자로 시작하는 이름으로 변경하십시오. 이렇게하면 변수가 패키지 외부에서 표시되지 않습니다.
type Company struct {
Name string `json:"name"`
Location string `json:"location"`
Revenue int `json:"-"`
sales int
}
빈 필드 무시
JSON이 0 값으로 설정되었을 때 Location
가 JSON에 포함되지 않도록하려면 json
태그에 ,omitempty
를 추가하십시오.
type Company struct {
Name string `json:"name"`
Location string `json:"location,omitempty"`
}
개인 필드가있는 구조체 마샬링
좋은 개발자로서 exported 필드와 unexported 필드 둘 다로 struct를 생성했습니다 :
type MyStruct struct {
uuid string
Name string
}
놀이터에서의 예 : https://play.golang.org/p/Zk94Il2ANZ
이제이 구조체를 etcd와 같은 저장소에 유효한 JSON으로 Marshal()
marshal)하려고합니다. 그러나 uuid
가 export되지 않기 때문에, json.Marshal()
은 그것을 건너 뜁니다. 무엇을해야합니까? 익명 구조체와 json.MarshalJSON()
인터페이스를 사용하십시오! 다음은 그 예입니다.
type MyStruct struct {
uuid string
Name string
}
func (m MyStruct) MarshalJSON() ([]byte, error {
j, err := json.Marshal(struct {
Uuid string
Name string
}{
Uuid: m.uuid,
Name: m.Name,
})
if err != nil {
return nil, err
}
return j, nil
}
놀이터에서의 예 : https://play.golang.org/p/Bv2k9GgbzE
Go 구조체를 사용한 인코딩 / 디코딩
City
타입을 정의하는 다음 struct
가 있다고 가정 해 보겠습니다.
type City struct {
Name string
Temperature int
}
우리는 encoding/json
패키지를 사용하여 City 값을 인코딩 / 디코딩 할 수 있습니다.
우선 Go 메타 데이터를 사용하여 구조체 필드와 JSON 키 사이의 통신을 인코더에 알릴 필요가 있습니다.
type City struct {
Name string `json:"name"`
Temperature int `json:"temp"`
// IMPORTANT: only exported fields will be encoded/decoded
// Any field starting with a lower letter will be ignored
}
이 예제를 간단하게하기 위해 필드와 키 사이에 명시적인 일치 성을 선언합니다. 그러나 json:
의 여러 변형을 사용할 수 있습니다. 문서에서 설명한대로 메타 데이터.
중요 : 내 보낸 필드 (자본 이름이있는 필드) 만 직렬화 / 역 직렬화됩니다. 이 필드 t의 이름을 예를 들어, 사용자가 설정 한 경우에도 무시됩니다 럼 온 json
메타 데이터를.
부호화
City
구조체를 인코딩하려면 기본 예제에서와 같이 json.Marshal
을 사용 json.Marshal
.
// data to encode
city := City{Name: "Rome", Temperature: 30}
// encode the data
bytes, err := json.Marshal(city)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
// {"name":"Rome","temp":30}
디코딩
City
구조체를 디코딩하려면 기본 예제와 같이 json.Unmarshal
을 사용 json.Unmarshal
.
// data to decode
bytes := []byte(`{"name":"Rome","temp":30}`)
// initialize the container for the decoded data
var city City
// decode the data
// notice the use of &city to pass the pointer to city
if err := json.Unmarshal(bytes, &city); err != nil {
panic(err)
}
fmt.Println(city)
// {Rome 30}