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. three.js:Failed to execute 'texImage2D' on 'WebGLRenderingContext解决方案

    three.js加载图片时,出现Failed to execute 'texImage2D' on 'WebGLRenderingContext .Tainted canvases may not b ...

  2. JS调用App方法及App调用JS方法

    做App内嵌H5项目时,经常会遇到js与App的交互,最普遍的就是方法的互相调用,那么如何实现方法的互相调用呢? 写在前面: 如果只是小项目且后期扩大的可能性不大的时候,可以忽略,可如果是长期项目的话 ...

  3. P2261 [CQOI2007]余数求和

    我是题面 题意还是很清晰,很容易理解 1e9范围明显不能暴力,除非你能把常数优化到\(\frac1 {10}\),但我实在想象不到用了这么多取模怎么把常数优化下去 我们可以把\(k\%i\)变成\(k ...

  4. 腾讯下载的视频qlv格式转化为MP4格式

    最近在看腾讯视频的时候发现下载下来的视频格式都是qlv格式,且不能用其他播放器播放,甚是恼怒,网上找了很多方法都很繁琐,于是自己写了一个小程序来处理这个问题.把下载下来的qlv格式转化为MP4格式 首 ...

  5. Extend to Palindrome UVA - 11475(补成回文串)

    题意: 就是用最少的字符把原字符串补成回文串 解析: emm/.../网上都是用kmp和后缀数组做的 我没想到这俩的思路...emmm... 想到了exkmp的  就是原串和逆串匹配一下  注意要保证 ...

  6. Luogu 3369 我用线段树骗了一道平衡树题……

    这篇博客毫无意义-- 只是表达一下我仍然会写树状数组和线段树-- 题目链接 #include <cstdio> #include <cstring> #include < ...

  7. MySQL总结小妙招

    mysql5.7版本,免登陆修改管理员密码: vim /etc/my.cnf 加入skip-grant-tables,重启MySQL 终端输入 mysql ,直接登录MySQL数据库,然后use my ...

  8. 解题:USACO14MAR Sabotage

    题面 题外话:我的实数二分有什么问题=.= 仍然(我为什么要这么说)是二分答案,如何检查呢?将所有的数减去二分出来的$mid$后求和得到和$sum$,然后如果在减出来的数列中能找出一段大于$sum$的 ...

  9. 3:JavaBean,EJB,POJO

    JavaBeanJavaBean是公共Java类,但是为了编辑工具识别,需要满足至少三个条件: 有一个public默认构造器(例如无参构造器,) 属性使用public 的get,set方法访问,也就是 ...

  10. 在MyBatis中,前台传数组批量传id处理数据方式

    <update id = "dishBatchSaleOrDown"> <if test="ids != null"> <if t ...