func NewEncoder(w io.Writer) Encoder
NewEncoder创建一个将数据写入w的Encoder。
func (enc *Encoder) Encode(v interface{}) error
Encode将v的json编码写入输出流,并会写入一个换行符
func Marshal(v interface{}) ([]byte, error)
Marshal函数返回v的json编码。
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
MarshalIndent类似Marshal但会使用缩进将输出格式化。
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
Indent函数将json编码的调整缩进之后写入dst。每一个json元素/数组都另起一行开始,以prefix为起始,一或多个indent缩进(数目看嵌套层数)。写入dst的数据起始没有prefix字符,也没有indent字符,最后也不换行,因此可以更好的嵌入其他格式化后的json数据里
// parse_json.go
package main
import (
// "bytes"
"encoding/json"
"fmt"
"os"
)
type user struct {
Name string
Age int
Sex bool
}
func main() {
var user_map = map[int]user{1: {"zhangsan", 20, true}, 2: {"lisi", 20, false}}
// 编码JSON数据并返回
bt_data, _ := json.Marshal(user_map)
fmt.Println(string(bt_data))
// 编码JSON数据并以缩进方式返回
indent_bt_data, _ := json.MarshalIndent(user_map, "", " ")
fmt.Println("indent_bt_data = ", string(indent_bt_data))
// 将编码完的JSON数据直接写入到文件中
json_w_fd, _ := os.OpenFile("./out.json", os.O_CREATE, 0666)
json_encoder := json.NewEncoder(json_w_fd)
json_encoder.Encode(user_map)
json_w_fd.Close()
// 将编码完的JSON数据合并到其他数据中
// dst := bytes.NewBuffer(indent_bt_data)
// json.Indent(dst, bt_data, "", "")
// fmt.Println(dst.String())
}
func NewDecoder(r io.Reader) Decoder
NewDecoder创建一个从r读取并解码json对象的Decoder,解码器有自己的缓冲,并可能超前读取部分json数据
func (dec *Decoder) Decode(v interface{}) error
Decode从输入流读取下一个json编码值并保存在v指向的值里,参见Unmarshal函数的文档获取细节信息。
func Unmarshal(data []byte, v interface{}) error
Unmarshal函数解析json编码的数据并将结果存入v指向的值。
Unmarshal和Marshal做相反的操作,必要时申请映射、切片或指针,有如下的附加规则:
要将json数据解码写入一个指针,Unmarshal函数首先处理json数据是json字面值null的情况。此时,函数将指针设为nil;否则,函数将json数据解码写入指针指向的值;如果指针本身是nil,函数会先申请一个值并使指针指向它。
要将json数据解码写入一个结构体,函数会匹配输入对象的键和Marshal使用的键(结构体字段名或者它的标签指定的键名),优先选择精确的匹配,但也接受大小写不敏感的匹配。
要将json数据解码写入一个接口类型值,函数会将数据解码为如下类型写入接口:
Bool 对应JSON布尔类型
float64 对应JSON数字类型
string 对应JSON字符串类型
[]interface{} 对应JSON数组
map[string]interface{} 对应JSON对象
nil 对应JSON的null
如果一个JSON值不匹配给出的目标类型,或者如果一个json数字写入目标类型时溢出,Unmarshal函数会跳过该字段并尽量完成其余的解码操作。如果没有出现更加严重的错误,本函数会返回一个描述第一个此类错误的详细信息的UnmarshalTypeError。
JSON的null值解码为go的接口、指针、切片时会将它们设为nil,因为null在json里一般表示“不存在”。 解码json的null值到其他go类型时,不会造成任何改变,也不会产生错误。
当解码字符串时,不合法的utf-8或utf-16代理(字符)对不视为错误,而是将非法字符替换为unicode字符U+FFFD。
// json_decode.go
package main
import (
// "bytes"
"encoding/json"
"fmt"
"os"
)
type user struct {
Name string
Age int
Sex bool
}
func main() {
var user_map map[int]user
// bt_data []byte
json_rd_fd, _ := os.Open("./out.json")
json_decode := json.NewDecoder(json_rd_fd)
json_decode.Decode(&user_map)
fmt.Println(user_map)
json_rd_fd.Close()
json_str := "{\"1\":{\"Name\":\"wangwu\",\"Age\":18,\"Sex\":true},\"2\":{\"Name\":\"chenliu\",\"Age\":29,\"Sex\":false}}"
json.Unmarshal([]byte(json_str), &user_map)
fmt.Println(user_map)
}
RawMessage类型是一个保持原本编码的json对象。本类型实现了Marshaler和Unmarshaler接口,用于延迟json的解码或者预计算json的编码。
即在第一次解码时,RawMessage类型的数据先保留JSON格式。
如下代码来自golang标准文档库
type Color struct {
Space string
Point json.RawMessage // delay parsing until we know the color space
}
type RGB struct {
R uint8
G uint8
B uint8
}
type YCbCr struct {
Y uint8
Cb int8
Cr int8
}
var j = []byte(`[
{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}},
{"Space": "RGB", "Point": {"R": 98, "G": 218, "B": 255}}
]`)
var colors []Color
err := json.Unmarshal(j, &colors)
if err != nil {
log.Fatalln("error:", err)
}
for _, c := range colors {
var dst interface{}
switch c.Space {
case "RGB":
dst = new(RGB)
case "YCbCr":
dst = new(YCbCr)
}
err := json.Unmarshal(c.Point, dst)
if err != nil {
log.Fatalln("error:", err)
}
fmt.Println(c.Space, dst)
}
YCbCr &{255 0 -10}
RGB &{98 218 255}