GO_Json

结构体转JSON 

package main

import (
    "encoding/json"
    "fmt"
)

type DebugInfo struct {
    Level  string
    Msg    string
    author string // 未导出字段不会被json解析
}

func main() {

    dbgInfs := []DebugInfo{
        DebugInfo{"debug", `File: "test.txt" Not Found`, "Cynhard"},
        DebugInfo{"", "Logic error", "Gopher"},
    }

    if data, err := json.Marshal(dbgInfs); err == nil {
        fmt.Printf("%s\n", data)
    }
}

// 输出
[{"Level":"debug","Msg":"File: \"test.txt\" Not Found"},{"Level":"","Msg":"Logic error"}]

 json包在解析匿名字段时,会将匿名字段的字段当成该结构体的字段处理

TAG中json可以指定转换后的属性名: `json:"level"` , TAG用,隔开

转换接口 在调用Marshal(v interface{})时,该函数会判断v是否满足json.Marshaler或者 encoding.Marshaler 接口,如果满足,则会调用这两个接口来进行转换(如果两个都满足,优先调用json.Marshaler)。这两个接口定义如下:

// json.Marshaler 
type Marshaler interface {
    MarshalJSON() ([]byte, error)
}

// encoding.TextMarshaler
type TextMarshaler interface {
    MarshalText() (text []byte, err error)
}

示例

package main

import (
    "encoding/json"
    "fmt"
)

type Point struct{ X, Y int }

func (pt Point)MarshalJSON() ([]byte, error) {
    return []byte(fmt.Sprintf(`{"X":%d,"Y":%d}`, pt.X, pt.Y)), nil
}

func main() {
    if data, err := json.Marshal(Point{50, 50}); err == nil {
        fmt.Printf("%s\n", data)
    }
}
// {"X":50,"Y":50}

  json包调用encoding.TextMarshaler接口处理转换时与调用json.Marshaler接口略有不同,例如将上例的MarshalJSON 改为MarshalText,使Point满足text.TextMarshaler: 

func (pt Point)MarshalText() ([]byte, error) { 
    return []byte(fmt.Sprintf("{\"X\":%d,\"Y\":%d}", pt.X, pt.Y)), nil 
}
//  "{\"X\":50,\"Y\":50}" 

可见json包在调用MarshalText时,给字符串加上了双引号:

Json转GO类型

转成内置类型

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    data := `[{"Level":"debug","Msg":"File: \"test.txt\" Not Found"},` +
        `{"Level":"","Msg":"Logic error"}]`

    var dbgInfos []map[string]string
    json.Unmarshal([]byte(data), &dbgInfos)

    fmt.Println(dbgInfos)
}

转成结构体

不区分大小写, 也可根据TAG来

在解码JSON时,如果找不到字段,则查找匿名字段的字段 

package main

import (
    "encoding/json"
    "fmt"
)

type DebugInfo struct {
    Level string
    Msg string
    author string  // 未导出字段不会被json解析
}

func (dbgInfo DebugInfo) String() string {
    return fmt.Sprintf("{Level: %s, Msg: %s}", dbgInfo.Level, dbgInfo.Msg)
}

func main() {
    data := `[{"level":"debug","msg":"File Not Found","author":"Cynhard"},` +
        `{"level":"","msg":"Logic error","author":"Gopher"}]`

    var dbgInfos []DebugInfo
    json.Unmarshal([]byte(data), &dbgInfos)

    fmt.Println(dbgInfos)
}

  和编码类似,解码时根据参数是否满足json.Unmarshaler和encoding.TextUnmarshaler来调用相应函数(若两个函数都存在,则优先调用UnmarshalJSON)。这两个接口定义如下

// json.Unmarshaler
type Unmarshaler interface {
    UnmarshalJSON([]byte) error
}

// encoding.TextUnmarshaler
type TextUnmarshaler interface {
    UnmarshalText(text []byte) error
}

  下例是一个使用json.Unmarshaler接口的例子

package main

import (
    "encoding/json"
    "fmt"
)

type Point struct{ X, Y int }

func (Point) UnmarshalJSON(data []byte) error {
    fmt.Println(string(data)) // {"X":80,"Y":80}
    return nil
}

func main() {
    data := `{"X":80,"Y":80}`
    var pt Point
    json.Unmarshal([]byte(data), &pt)
}

  

posted @ 2018-09-23 19:33  瓜田月夜  阅读(130)  评论(0)    收藏  举报