go json与struct相互映射注意问题

1、无tag标签时,只要单词字母一样(不区分大小写),就能映射成功


type MyRequest struct {
    Id          string `json:"im"`
    Device      MyDevice
    Secure      int
    Status_Code int   // 都要有下划线才行
}

type MyDevice struct {
    Ip   string
    Type int
}

func UnMarsh() {
    s := `{"im": "123", "device":{"ip":"127.0.0.1"}, "sEcUrE":3, "status_code": 200}`
    // s := `{"im": "123", "sEcUrE":3}`
    var req MyRequest
    err := json.Unmarshal([]byte(s), &req)
    if err != nil {
        panic(err)
    }
    fmt.Println(req)
}

输出

{123 {127.0.0.1 0} 3 200}
//{123 { 0} 3 0} 未定义的都会被初始化

2、struct中嵌入struct,内嵌struct无值传入也会初始化,这样不太好判断是否有值传入,可以内嵌struct指针,判断nil

type MyRequest struct {
    Id string `json:"im"`
    Device *MyDevice
    Secure int
}

type MyDevice struct {
    Ip string
    Type int
}

func UnMarsh () {
    s := `{"im": "123", "device":{"ip":"127.0.0.1"}, "sEcUrE":3}`
    // s := `{"im": "123", "sEcUrE":3}`
    var req MyRequest
    err := json.Unmarshal([]byte(s), &req)
    if err != nil {
        panic(err)
    }
    fmt.Println(req)
}

输出

{123 0xc0000585a0 3}
// {123  3}

3、omitempty只对会基本类型起作用,对结构体不起作用,可以改称指针

package jm

import (
    "encoding/json"
    "fmt"
    "log"
)

type MyRequest struct {
    Id     string      `json:"id,omitempty"`
    Device []*MyDevice `json:"device,omitempty"`
    Secure int         `json:"secure,omitempty"`
    Ext    *MyExt      `json:"ext,omitempty"`
}

type MyExt struct {
    City string
}

type MyDevice struct {
    Ip    string   `json:"ip,omitempty"`
    Type  int      `json:"type,omitempty"`
    App   MyApp   `json:"app,omitempty"` // 注意该值
    Model []string `json:"model,omitempty"`
}

type MyApp struct {
    Name string
}

func Marsh() {
    var req MyRequest
    req.Id = "123"
    var devs []*MyDevice
    var device MyDevice
    device.Ip = "0.0.0.0"
    devs = append(devs, &device)
    req.Device = devs
    if bs, err := json.Marshal(req); err != nil {
        log.Fatal(err)
    } else {
        fmt.Println(string(bs)) // {"id":"123","device":[{"ip":"0.0.0.0","app":{"Name":""}}]}
    }
}

改成指针

package jm

import (
    "encoding/json"
    "fmt"
    "log"
)

type MyRequest struct {
    Id     string      `json:"id,omitempty"`
    Device []*MyDevice `json:"device,omitempty"`
    Secure int         `json:"secure,omitempty"`
    Ext    *MyExt      `json:"ext,omitempty"`
}

type MyExt struct {
    City string
}

type MyDevice struct {
    Ip    string   `json:"ip,omitempty"`
    Type  int      `json:"type,omitempty"`
    App   *MyApp   `json:"app,omitempty"`
    Model []string `json:"model,omitempty"`
}

type MyApp struct {
    Name string
}

func Marsh() {
    var req MyRequest
    req.Id = "123"
    var devs []*MyDevice
    var device MyDevice
    device.Ip = "0.0.0.0"
    devs = append(devs, &device)
    req.Device = devs
    if bs, err := json.Marshal(req); err != nil {
        log.Fatal(err)
    } else {
        fmt.Println(string(bs)) // {"id":"123","device":[{"ip":"0.0.0.0"}]}
    }
}

4、赋值问题

package jm

import (
    "encoding/json"
    "fmt"
    "log"
)

type MyRequest struct {
    Id     string      `json:"id,omitempty"`
    Device []*MyDevice `json:"device,omitempty"`
    Secure int         `json:"secure,omitempty"`
    Ext    *MyExt      `json:"ext,omitempty"`
}

type MyExt struct {
    City string
}

type MyDevice struct {
    Ip   string `json:"ip,omitempty"`
    Type int    `json:"type,omitempty"`
    App  *MyApp `json:"app,omitempty"`
}

type MyApp struct {
    Name  string
    Hobby []*MyHobby
}

type MyHobby struct {
    H string
}

func Marsh() {
    var req MyRequest
    req.Id = "123"
    var devs []*MyDevice
    var device MyDevice
    device.Ip = "0.0.0.0"
    device.App.Name = "T" //panic: runtime error: invalid memory address or nil pointer dereference
    //var app MyApp
    //app.Name = "an"
    //var hob MyHobby
    //hob.H = "sing"
    //app.Hobby = append(app.Hobby, &hob)
    //device.App = &app
    //devs = append(devs, &device)
    req.Device = devs
    if bs, err := json.Marshal(req); err != nil {
        log.Fatal(err)
    } else {
        fmt.Println(string(bs))
    }
}

正确赋值

package jm

import (
    "encoding/json"
    "fmt"
    "log"
)

type MyRequest struct {
    Id     string      `json:"id,omitempty"`
    Device []*MyDevice `json:"device,omitempty"`
    Secure int         `json:"secure,omitempty"`
    Ext    *MyExt      `json:"ext,omitempty"`
}

type MyExt struct {
    City string
}

type MyDevice struct {
    Ip   string `json:"ip,omitempty"`
    Type int    `json:"type,omitempty"`
    App  *MyApp `json:"app,omitempty"`
}

type MyApp struct {
    Name  string
    Hobby []*MyHobby
}

type MyHobby struct {
    H string
}

func Marsh() {
    var req MyRequest
    req.Id = "123"
    var devs []*MyDevice
    var device MyDevice
    device.Ip = "0.0.0.0"
    //device.App.Name = "T" //panic: runtime error: invalid memory address or nil pointer dereference
    var app MyApp
    app.Name = "an"
    var hob MyHobby
    hob.H = "sing"
    app.Hobby = append(app.Hobby, &hob) // slice元素是指针可以直接append
    device.App = &app
    device.Type = 0 // 类型零值会被omitempty,需要注意,json转struct没有此问题
    devs = append(devs, &device)
    req.Device = devs
    if bs, err := json.Marshal(req); err != nil {
        log.Fatal(err)
    } else {
        fmt.Println(string(bs)) // {"id":"123","device":[{"ip":"0.0.0.0","app":{"Name":"an","Hobby":[{"H":"sing"}]}}]}
    }
}

你可能感兴趣的:(go json与struct相互映射注意问题)