• Go语言标准库之JSON编解码


    Go语言标准库之JSON编解码

    基本的类型

    Go语言中的数据类型和JSON的数据类型的关系

    • bool -> JSON boolean
    • float64 -> JSON numbers
    • string -> JSON strings
    • nil -> JSON null
    Struct to JSON

    Goencoding/json中的json.Marshal方法,可以将struct编码为JSON数据

    package main
    
    import (
        "encoding/json"
        "fmt"
        "time"
    )
    
    type FruitBasket struct {
        Name    string
        Fruit   []string
        Id      int64  `json:"ref"`
        private string // 这个字段不会被编码
        Created time.Time
    }
    
    func main() {
        basket := FruitBasket{
            Name:    "Standard",
            Fruit:   []string{"Apple", "Banana", "Orange"},
            Id:      999,
            private: "Second-rate",
            Created: time.Now(),
        }
    
        jsonData, err := json.Marshal(basket)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println(string(jsonData))
    }
    

    输出结果

    {"Name":"Standard","Fruit":["Apple","Banana","Orange"],"ref":999,"Created":"2019-01-01T11:40:05.9885387+08:00"}
    
    • 只有public字段才能被导出
    • json:tag可以定义导出字段的名称
    • nil导出为null
    格式化输出

    可以使用 json.MarshalIndent方法来格式化输出的JSON数据

     formatData, err := json.MarshalIndent(basket, "", "    ")
    fmt.Println(string(formatData))
    

    格式化输出结果是

    {
        "Name": "Standard",
        "Fruit": [
            "Apple",
            "Banana",
            "Orange"
        ],
        "ref": 999,
        "Created": "2019-01-01T11:45:49.0969176+08:00"
    }
    
    JSON to Struct

    Go包中json.Unmarshal方法,解析 JSON数据

      jsonStr := []byte(`
        {
            "Name": "Standard",
            "Fruit": [
                "Apple",
                "Banana",
                "Orange"
            ],
            "ref": 999,
            "Created": "2019-01-01T11:45:49.0969176+08:00"
        }
        `)
    
        var basketStruct FruitBasket
        err = json.Unmarshal(jsonStr, &basketStruct)
        if err != nil {
            log.Println(err)
        }
        fmt.Println(basketStruct.Name, basketStruct.Fruit)
        fmt.Println(basketStruct.Created)
    

    输出结果是

    Standard [Apple Banana Orange]
    2019-01-01 11:45:49.0969176 +0800 CST
    
    编码格式化任意类型的对象和数组

    map[string]interface{}可以编码任意类型的 JSON 对象
    []interface{}可以编码任意类型的JSON数组

     arbitData := []byte(`{"Name":"Eve","Age":6,"Parents":["Alice","Bob"]}`)
        var v interface{}
        err = json.Unmarshal(arbitData, &v)
        if err != nil {
            log.Println(err)
        }
        data := v.(map[string]interface{})
        for k, v := range data {
            switch v := v.(type) {
            case string:
                fmt.Println(k, v, "(string)")
            case float64:
                fmt.Println(k, v, "(float64)")
            case []interface{}:
                fmt.Println(k, v, "(array)")
                for i, u := range v {
                    fmt.Println("    ", i, u)
                }
            default:
                fmt.Println(k, v, "(unknown)")
            }
        }
    

    输出结果是

    Name Eve (string)
    Age 6 (float64)
    Parents [Alice Bob] (array)
         0 Alice
         1 Bob
    
    编解码JSON文件

    Goencoding/json中的json.Decoderjson.Encoder方法可以编解码JSON格式文件

    例子:

       jsonstr := `
        {"Name": "Alice", "Age": 25}
        {"Name": "Bob", "Age": 22}`
        reader := strings.NewReader(jsonstr)
        writer := os.Stdout
    
        dec := json.NewDecoder(reader)
        enc := json.NewEncoder(writer)
    
        for {
            var m map[string]interface{}
            if err := dec.Decode(&m); err == io.EOF {
                break
            } else if err != nil {
                log.Fatal(err)
            }
    
            for k := range m {
                if k == "Age" {
                    delete(m, k)
                }
            }
    
            if err = enc.Encode(&m); err != nil {
                log.Println(err)
            }
        }
    

    输出结果是

    {"Name":"Alice"}
    {"Name":"Bob"}
    
  • 相关阅读:
    学习 Message(12): 整合鼠标 Down 消息
    合并两个 Wav 文件流的函数 回复 "刘文强" 的问题
    “博客无双”第一期拍卖活动获奖名单公告
    [获奖公告]“博客无双”12月27日第一期获奖名单
    “博客无双”活动拍卖时间调整公告
    致歉
    祝大家新年快乐
    博客园电子期刊2010年12月刊发布啦
    “博客无双”拍卖活动将于14:00开始
    2011年4月微软最有价值专家(MVP)申请截止时间:2011年1月13日
  • 原文地址:https://www.cnblogs.com/guigujun/p/10206233.html
Copyright © 2020-2023  润新知