json就是简单的数据交换格式,语法类似javascript的对象和列表,是最常见的后端和运行在网页上的js之间的通信格式。

encoding:

编码json数据需要使用到Marshal()函数。

func Marshal(v interface{}) ([]byte, error)
type Message struct {
Name string
Body string
Time int64
}
m := Message{"Alice", "Hello", }
b, err := json.Marshal(m)
b == []byte(`{"Name":"Alice","Body":"Hello","Time":}`)

上面的代码就是讲一个Message对象编码成json的格式。json格式的显示是[]byte类型的。

decoding:

解码json格式的数据使用到的是Unmarshal()函数。

func Unmarshal(data []byte, v interface{}) error
var m Message
err := json.Unmarshal(b, &m)

Unmarshal()接受的是[]byte类型的json数据,和这个数据要返回的结构体的指针。

在Unmarshal()函数中。只能识别在m这个结构体中所拥有的属性字段。不存在的将会被忽略。

通用的json接口:interface{}

任意的go类型都实现了空接口interface{}

var i interface{}
i = "a string"
i =
i = 2.777

可以使用断言来判断它的实现类型

r := i.(float64)
fmt.Println("the circle's area", math.Pi*r*r)

如果不知道实现的类型,可以使用swtich case来片判断

switch v := i.(type) {
case int:
fmt.Println("twice i is", v*)
case float64:
fmt.Println("the reciprocal of i is", /v)
case string:
h := len(v) /
fmt.Println("i swapped by halves is", v[h:]+v[:h])
default:
// i isn't one of the types above
}

json包使用map[string]interface{}和[]interface{}来存储任意的json对象和数组。go的类型和json的类型对应如下:

  • bool for JSON booleans,
  • float64 for JSON numbers,
  • string for JSON strings,
  • nil for JSON null.

解码任意数据data

假设b中存储的书json数据

b := []byte(`{"Name":"Wednesday","Age":,"Parents":["Gomez","Morticia"]}`)

当不知道这个数据的结构体的时候,可以使用Unmarshal()来将它解码成一个interface{}的值。

var f interface{}
err := json.Unmarshal(b, &f)

f现在的数据结构就是一个map[string]interface{}

f = map[string]interface{}{
"Name": "Wednesday",
"Age": ,
"Parents": []interface{}{
"Gomez",
"Morticia",
},
}

可以使用断言f的底层接口来访问这些数据

m := f.(map[string]interface{})

然后遍历这个map,利用switch case来断言底层的类型

for k, v := range m {
switch vv := v.(type) {
case string:
fmt.Println(k, "is string", vv)
case int:
fmt.Println(k, "is int", vv)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range vv {
fmt.Println(i, u)
}
default:
fmt.Println(k, "is of a type I don't know how to handle")
}
}

Reference Types:

type FamilyMember struct {
Name string
Age int
Parents []string
} var m FamilyMember
err := json.Unmarshal(b, &m)

将b中的[]byte数据编码到FamilyMember结构体中去,首先给FamilyMember 分配内存,然后传入一个指针到Unmarshal中去。但是属性Parents是一个nil空值,unmarshal给这个slice分配一个新的块。

Let's define a Go type to contain the data from the previous example:

type FamilyMember struct {
Name string
Age int
Parents []string
} var m FamilyMember
err := json.Unmarshal(b, &m)

Unmarshaling that data into a FamilyMember value works as expected, but if we look closely we can see a remarkable thing has happened. With the var statement we allocated a FamilyMember struct, and then provided a pointer to that value toUnmarshal, but at that time the Parents field was a nil slice value. To populate the Parents field, Unmarshal allocated a new slice behind the scenes. This is typical of how Unmarshal works with the supported reference types (pointers, slices, and maps).

Consider unmarshaling into this data structure:

type Foo struct {
Bar *Bar
}

If there were a Bar field in the JSON object, Unmarshal would allocate a new Bar and populate it. If not, Bar would be left as a nil pointer.

From this a useful pattern arises: if you have an application that receives a few distinct message types, you might define "receiver" structure like

type IncomingMessage struct {
Cmd *Command
Msg *Message
}

and the sending party can populate the Cmd field and/or the Msg field of the top-level JSON object, depending on the type of message they want to communicate. Unmarshal, when decoding the JSON into an IncomingMessage struct, will only allocate the data structures present in the JSON data. To know which messages to process, the programmer need simply test that either Cmd or Msg is not nil.

Streaming Encoders and Decoders

The json package provides Decoder and Encoder types to support the common operation of reading and writing streams of JSON data. The NewDecoder and NewEncoder functions wrap the io.Reader and io.Writer interface types.

func NewDecoder(r io.Reader) *Decoder
func NewEncoder(w io.Writer) *Encoder

Here's an example program that reads a series of JSON objects from standard input, removes all but the Name field from each object, and then writes the objects to standard output:

package main

import (
"encoding/json"
"log"
"os"
) func main() {
dec := json.NewDecoder(os.Stdin)
enc := json.NewEncoder(os.Stdout)
for {
var v map[string]interface{}
if err := dec.Decode(&v); err != nil {
log.Println(err)
return
}
for k := range v {
if k != "Name" {
delete(v, k)
}
}
if err := enc.Encode(&v); err != nil {
log.Println(err)
}
}
}

Due to the ubiquity of Readers and Writers, these Encoder and Decoder types can be used in a broad range of scenarios, such as reading and writing to HTTP connections, WebSockets, or files.

golang的json序列化的更多相关文章

  1. Golang之json序列化(struct,int,map,slice)

    老规矩,直接上代码 package main import ( "encoding/json" "fmt" ) //把结构体都改小写 type User str ...

  2. golang的json序列化问题

    首先看一段代码: package main import ( "encoding/json" "fmt" ) type Result struct { //st ...

  3. golang中json包序列化与反序列化

    package main import ( "encoding/json" "fmt" "reflect" ) type Info stru ...

  4. Golang的Json encode/decode以及[]byte和string的转换

    使用了太长时间的python,对于强类型的Golang适应起来稍微有点费力,不过操作一次之后发现,只有这么严格的类型规定,才能让数据尽量减少在传输和解析过程中的错误.我尝试使用Golang创建了一个公 ...

  5. golang数据传输格式-序列化与反序列化

    golang数据传输格式-序列化与反序列化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 想必计算机专业毕业的小伙伴应该都知道数据想要持久化存储,必须将其存在I/O设备里面,这些I ...

  6. Golang 处理 Json(二):解码

    golang 编码 json 还比较简单,而解析 json 则非常蛋疼.不像 PHP 一句 json_decode() 就能搞定.之前项目开发中,为了兼容不同客户端的需求,请求的 content-ty ...

  7. Golang 处理 Json(一):编码

    JSON 是一种数据格式描述语言.以 key 和 value 构成的哈系结构,类似 Javascript 中的对象,python 中的字典.通常 json 格式的 key 是字符串,其值可以是任意类型 ...

  8. Golang的json包

    encoding/json encoding/json是官方提供的标准json, 实现RFC 7159中定义的JSON编码和解码.使用的时候需要预定义struct,原理是通过reflection和in ...

  9. .Net深入实战系列—JSON序列化那点事儿

    序 当前主流的序列化JSON字符串主要有两种方式:JavaScriptSerializer及Json.net(Nuget标识:Newtonsoft.Json).JavaScriptSerializer ...

随机推荐

  1. linux下安装java jdk

    第一步:查看java对应版本               yum search java 我自己装的是1.8版本的java包 第二步:装java包 yum install java-1.8.0-ope ...

  2. Spring Cloud与微服务构建:微服务简介

    Spring Cloud与微服务构建:微服务简介 单体架构及其不足 1.单体架构简介 在软件设计中,经常提及和使用经典的3曾模型,即表示层.业务逻辑层和数据访问层. 表示层:用于直接和用户交互,也成为 ...

  3. MySql数据库迁移图文展示

    MySql数据库的数据从一台服务器迁移到另外一台服务器需要将数据库导出,再从另外一台服务器导入.方法有很多,MySql配套的相关工具都有这个功能.phpMyAdmin就可以做,但是这个加载起来慢,推荐 ...

  4. 使用jQuery在javascript中自定义事件

    js中的自定义事件有attachEvent,addEventListener等等好多种,往往受困于浏览器兼容,而且代码写起来也相当麻烦.jQuery为我们解决了这个问题,几行代码就可以很好的实现事件的 ...

  5. easyui的datebox只显示年月

    要求点击easyui的datebox时只显示年月,隐藏日,之前百度了好多,发现有的好麻烦,有的使用没效果,也许自己没理解,改不了.最后老员工帮我搞定了,添加一个fomatter和一个parser函数就 ...

  6. BZOJ 2521: [Shoi2010]最小生成树

    2521: [Shoi2010]最小生成树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 445  Solved: 262[Submit][Statu ...

  7. 【BZOJ3675】【Apio2014】序列分割

    Description 传送门 Solution ​ 之前我也遇到过一次这种"两段之和乘积作为贡献"的问题:考虑把这一种\((\sum) *(\sum)\)的形式拆括号,就可以发现 ...

  8. linux内核分析 第八周 理解进程调度时机跟踪分析进程调度与进程切换的过程

    笔记: 实验:使用gdb跟踪分析一个schedule()函数

  9. 最新版的Android4.4.2 SDK无法下载解决

    http://hi.baidu.com/petercao2008/item/65362d2bdbddfacba5275a50 问题: Downloading ARM EABI v7a System I ...

  10. 关于表单中Readonly和Disabled

    Readonly和Disabled是用在表单中的两个属性,它们都能够做到使用户不能够更改表单域中的内容.但是它们之间有着微小的差别,总结如下: Readonly只针对input(text / pass ...