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. java 数字转中文

    java代码 数字转中文,该方法只做了对int型整数的转换 private static String numberToChinese(int number) { String[] numbers = ...

  2. DPM(Deformable Parts Model)

    DPM(Deformable Parts Model) Reference: Object detection with discriminatively trained partbased mode ...

  3. BZOJ3277 串(后缀数组+二分答案+主席树)

    因为不会SAM,考虑SA.将所有串连起来并加分隔符,每次考虑计算以某个位置开始的子串有多少个合法. 对此首先二分答案,找到名次数组上的一个区间,那么只需要统计有多少个所给串在该区间内出现就可以了.这是 ...

  4. python之冒泡排序

    重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.def Bubble_Sort(lists): ...

  5. WEB入门.五 页面设计简介

    学习内容 Ø        XHTML 的发展历程 Ø        XHTML 和 HTML 的区别 Ø        XHTML的DOCTYPE和基本标签 Ø        CSS 常用属性 能力 ...

  6. 解题:POI 2015 PUS

    题面 还以为是差分约束,原来拓扑排序也能解决这样的问题=.= 类似差分约束的建图方式,我们把大小关系看做有向边.这样一来图上是不允许存在环的,于是我们可以做拓扑排序.然后问题来了,边数非常大,根本建不 ...

  7. mac下Android Studio使用及快捷键

    1.Android Studio使用及快捷键 (1)我们新建一个项目后进入界面,左侧可以选择Project或Android,一般选Project会比较习惯以前eclipse的显示 (2)点击左上角An ...

  8. 关于strassen矩阵乘法的矩阵大小不是2^k的形式时,时间复杂度是否还是比朴素算法好的看法

    原来是n,找到大于等于n且是2^k形式的数m.n*n的矩阵补全为m*m的矩阵,原来的矩阵放在最左上方,其它位置的值为0.朴素方法:n^3现在:m^2.8即m/n需小于e^(3/2.8)=2.919才能 ...

  9. Ntp服务器的搭建

    在搭建Ntp服务器的过程中,试过两种方案,具体如下: 方案一: 到ntp官网获取源码编译,失败   下载源码ntp-4.2.8 -> ./configure -> make 无法通过:   ...

  10. Hystrix的回退和zuul的回退总结

    1.Hystrix的回退: Ribbon: Feign: zuul的回退: