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. HDU4722——Good Numbers——2013 ACM/ICPC Asia Regional Online —— Warmup2

    今天比赛做得一个数位dp. 首先声明这个题目在数位dp中间绝对是赤裸裸的水题.毫无技巧可言. 题目的意思是个你a和b,要求出在a和b中间有多少个数满足数位上各个数字的和为10的倍数. 显然定义一个二维 ...

  2. [cdqzds] Challenge4

    描述 给一个长为N的数列,有M次操作,每次操作时以下三种之一: (1)修改数列中的一个数 (2)求数列中某连续一段所有数的两两乘积的和 mod 1000000007 (3)求数列中某连续一段所有相邻两 ...

  3. python mysql开发日志

    开始做python 的数据库访问了,暂时选定了mysql数据库.原本想使用ORM,后来考虑到项目的情况是:表结构不复杂,但是数据库非常大.还是自己来操作sql,不过PYTHON的那些数据库ORM的代码 ...

  4. innobackupx备份原理

    1.工具内容 该软件安装完成会有四个工具,如下所示: usr├── bin│ ├── innobackupex│ ├── xbcrypt│ ├── xbstream│ └── xtrabackup 其 ...

  5. Vivian's Problem UVA - 1323(梅林素数+状压二进制)

    借鉴:https://blog.csdn.net/miku23736748/article/details/52135932 https://blog.csdn.net/acm_cxlove/arti ...

  6. C++ STL 常用排序算法

    C++ STL 常用排序算法 merge() 以下是排序和通用算法:提供元素排序策略 merge: 合并两个有序序列,存放到另一个序列. 例如: vecIntA,vecIntB,vecIntC是用ve ...

  7. RocketMQ生产者消息篇

    系列文章 RocketMQ入门篇 RocketMQ生产者流程篇 RocketMQ生产者消息篇 前言 上文RocketMQ生产者流程篇中详细介绍了生产者发送消息的流程,本文将重点介绍发送消息的通信模式以 ...

  8. Android Support Palette使用详解

    使用Palette API选择颜色 良好的视觉设计是app成功所必不可少的, 而色彩设计体系是设计的基础构成. Palette包是支持包, 能够从图片中解析出突出的颜色, 从而帮助你创建出视觉迷人的应 ...

  9. 【Learning】分数规划

    分数规划 ​ 分数规划是一类决策性问题.一般地,题目会要求你针对问题规划一种方案,使得其代价函数最小或最大.其中,代价函数一般是分数形式,且分子分母的构成元素一般呈现一一对应关系. 直接上例题观察:B ...

  10. Java考试题之七

    QUESTION 150 Click the Exhibit button. Given: ClassA a = new ClassA(); a.methodA(); What is the resu ...