수색…


통사론

  • 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
}

특정 필드 숨기기 / 건너 뛰기

RevenueSales 를 내보내고 인코딩 및 디코딩에서 숨기려면 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} 

운동장



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow