10.json

golang 语言标准库 encoding/json

结构体slice 转 JSON 叫编组

编码时 , 通过反射技术 , 只有导出(首字母大写)的成员才会被编码

通道、复数、函数类型的值不能编码进json。

json.Marshal 编码

返回没有空格的紧凑字节数组

1
data, err := json.Marshal(movies)

json.MarshalIndent 格式化编码

返回包含空格的格式化字节数组

参数 2 : 每一行的输出前缀

参数 3 : 层级缩进

1
data, err := json.MarshalIndent(movies, "", "    ")

**Unmarshal ** 解码

首先处理json数据是json字面值null的情况。此时,函数将指针设为nil;否则,函数将json数据解码写入指针指向的值;如果指针本身是nil,函数会先申请一个值并使指针指向它。

1
2
3
4
var titles []struct{ Title string }
if err := json.Unmarshal(data, &titles); err != nil {
    log.Fatalf("JSON unmarshaling failed: %s", err)
}

结构体中只有Title成员。通过定义合适的Go语言数据结构,我们可以选择性地解码JSON中感兴趣的成员。

Decoder 流解码器

还有 Encoder 流编码器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
type IssuesSearchResult struct {
    TotalCount int `json:"total_count"`
    Items          []*Issue
}
var result IssuesSearchResult

// 发起网络请求, 拿到  resp.body
// 此处对流解码 , 也可以使用 ioutil.ReadALL 来读取流数据
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
        resp.Body.Close()
        return nil, err
}

tag

Tag可以是任意的字符串面值 , 通常是一系列用空格分隔的key:“value"键值对序列;

json开头键名对应的值用于控制encoding/json包的编码和解码的行为

json:"color" 编码后的名字为 color

json:",omitempty" 名字为变量名, 该类型若为零值 或 nil, 不会被编码

json:"-" 忽略, 不会被编码

json:",string" 编码时为字符串, 仅适用于变量为 字符串、浮点数、整数类型的字段

omitempty :

1
2
3
4
type movies struct{
  Year  int  `json:"released"`
  Color bool `json:"color,omitempty"`
}

匿名结构体编码

1
2
3
4
5
6
7
8
9
type Page struct {
	Color int
	Size  int
}

type Book struct {
	Page
	Size int
}
  1. book 中 Size 与 page 中 Size 命名冲突, page 的 Size 不会被编码
  2. 编码后{"Color":255,"Size":12}

对特殊字符转义操作 url.QueryEscape

在 URL 中加入查询参数, 避免 ? & 等歧义 , 可以先使用 url.QueryEscape 转义

1
2
q := url.QueryEscape(strings.Join(terms, " "))
    resp, err := http.Get(IssuesURL + "?q=" + q)

Json反序列化数字到interface{}类型的值中,默认解析为float64类型,在使用时要注意。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var data = []byte(`{"status": 200}`)

  var result map[string]interface{}
  if err := json.Unmarshal(data, &result); err != nil {
    fmt.Println("error:", err)
    return
  }

  //var status = result["status"].(int) //error: panic: interface conversion: interface is float64, not int 
  var status = uint64(result["status"].(float64)) //ok
  fmt.Println("status value:",status)
Licensed under CC BY-NC-SA 4.0
本文阅读量 次, 总访问量 ,总访客数
Built with Hugo .   Theme Stack designed by Jimmy