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

浙公网安备 33010602011771号