Golang进阶Golang与区块链

【Golang】json自定义序列化的深入解析

2018-05-10  本文已影响7人  qishuai

对于使用结构体中嵌套结构体的情况,只有receiver为指针类型,而嵌套结构体为结构体的值语义的时候不能触发自定义Json格式化函数MarshalJSON;其他三种组合均能够触发。

对于使用结构体中嵌套结构体slice的情况,receiver值语义、指针语义和嵌套结构体slice元素为值语义、指针语义的四种组合均能够触发Json格式化函数MarshalJSON。

package main

import (
    "encoding/json"
    "fmt"
)

type Profile struct {
    Level string
    Admin bool
}

// 本质是将Profile指针类型实现Marshaler接口,从而达到自定义json序列化格式的目的。
func (p *Profile) MarshalJSON() ([]byte, error) {
    if p.Admin {
        admin := struct {
            Level string
        }{
            Level: "admin",
        }
        return json.Marshal(admin)
    }

    control := struct {
        Level string
        Admin bool
    }{
        Level: "control",
        Admin: false,
    }
    return json.Marshal(control)
}

type User struct {
    Id      int
    Name    string
    Age     uint8
    Profile *Profile
}

func main() {
    u := User{
        Id:   1,
        Age:  23,
        Name: "qshuai",
        Profile: &Profile{
            Level: "master",
            Admin: true,
        },
    }
    b, err := json.Marshal(u)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(b))
}

// -----------------------------slice作为Struct成员的情况----------------------------
package main

import (
    "encoding/json"
    "fmt"
)

type Profile struct {
    Level string
    Admin bool
}

func (p *Profile) MarshalJSON() ([]byte, error) {
    if p.Admin {
        admin := struct {
            Level string
        }{
            Level: "admin",
        }
        return json.Marshal(admin)
    }

    control := struct {
        Level string
        Admin bool
    }{
        Level: "control",
        Admin: false,
    }
    return json.Marshal(control)
}

type User struct {
    Id      int
    Name    string
    Age     uint8
    Profile []Profile
}

func main() {
    u := User{
        Id:   1,
        Age:  23,
        Name: "qshuai",
        Profile: []Profile{
            {
                Level: "master",
                Admin: true,
            },
        },
    }
    b, err := json.Marshal(u)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(b))
}
上一篇下一篇

猜你喜欢

热点阅读