golang的json序列化
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序列化的更多相关文章
- Golang之json序列化(struct,int,map,slice)
老规矩,直接上代码 package main import ( "encoding/json" "fmt" ) //把结构体都改小写 type User str ...
- golang的json序列化问题
首先看一段代码: package main import ( "encoding/json" "fmt" ) type Result struct { //st ...
- golang中json包序列化与反序列化
package main import ( "encoding/json" "fmt" "reflect" ) type Info stru ...
- Golang的Json encode/decode以及[]byte和string的转换
使用了太长时间的python,对于强类型的Golang适应起来稍微有点费力,不过操作一次之后发现,只有这么严格的类型规定,才能让数据尽量减少在传输和解析过程中的错误.我尝试使用Golang创建了一个公 ...
- golang数据传输格式-序列化与反序列化
golang数据传输格式-序列化与反序列化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 想必计算机专业毕业的小伙伴应该都知道数据想要持久化存储,必须将其存在I/O设备里面,这些I ...
- Golang 处理 Json(二):解码
golang 编码 json 还比较简单,而解析 json 则非常蛋疼.不像 PHP 一句 json_decode() 就能搞定.之前项目开发中,为了兼容不同客户端的需求,请求的 content-ty ...
- Golang 处理 Json(一):编码
JSON 是一种数据格式描述语言.以 key 和 value 构成的哈系结构,类似 Javascript 中的对象,python 中的字典.通常 json 格式的 key 是字符串,其值可以是任意类型 ...
- Golang的json包
encoding/json encoding/json是官方提供的标准json, 实现RFC 7159中定义的JSON编码和解码.使用的时候需要预定义struct,原理是通过reflection和in ...
- .Net深入实战系列—JSON序列化那点事儿
序 当前主流的序列化JSON字符串主要有两种方式:JavaScriptSerializer及Json.net(Nuget标识:Newtonsoft.Json).JavaScriptSerializer ...
随机推荐
- 如何在Windows下查看JAVA端口占用情况(阿里面试)
如需要确定谁占用了9050端口 为例: 1.Windows平台 在windows命令行窗口下执行: 1.查看所有的端口占用情况 C:\>netstat -ano 协议 本地地址 外部地址 状态 ...
- mysql中while循环以及变量声明以及dilimiter
首先我们查看一个正确的完整的一个存储过程 ①其中delimiter命令解释如下:默认情况下,delimiter是分号:.在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令 ...
- hdu-3308 LCIS (线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- 内容显示在HTML页面底端的一些处理方式
1.概要: 手机页面底端有时候需要显示版权信息,诸如一行文字或者一个背景图片,但是页面的滚动长度未知,需要考虑两个问题 当页面高度小于屏幕高度时候: 希望最后一行信息显示在屏幕底端,同时也就是页面底端 ...
- 【CF438E】小朋友和二叉树 解题报告
[CF438E]小朋友和二叉树 Description 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树. 考虑一个含有\(n\)个互异正整数的序列\(c_1,c_2,\dots,c_n\). ...
- 单点登录(七)-----实战-----cas server去掉https验证
我们在搭建cas中已经说过如果不搭建https证书体系的需要去掉https的验证: 单点登录(二)----实战------简单搭建CAS---测试认证方式搭建CAS 因为cas4.2以上的代码做了一些 ...
- Jenkins(三)---Jenkins初始配置和插件配置
从Jenkins(二)中可以知道 jenkins 的工作目录为/opt/jenkins [很重要!!!][很重要!!!][很重要!!!]在配置此目录以前,将这两台的主机进行配置为ssh root用户无 ...
- 北京联通IPTV 数码视讯 Q1 破解过程
1. 买个usb转ttl的线,我买的是ch340g,3.8元包邮,店家貌似叫telesky,不重要,买到这货就行,里面有送杜邦线 2. 电脑上安装ch340g驱动,注意不要安装错了,注意电压的设置保持 ...
- RabbitMQ 运转流程
生产者发送消息 1.生产者连接到 RabbitMQ Broker,建立一个连接(Connection),开启一个信道(Channel) 2.生产者声明一个交换器,并设置相关属性,比如交换机类型.是否持 ...
- error: Failed to start domain lb error: Failed to activate service 'org.freedesktop.machine1': timed out 报错的解决办法
能正常查看kvm虚拟机列表: virsh list 但在执行virsh start lb启动虚拟机时卡顿了好几秒,然后报以下错误: error: Failed to start domain lber ...