@


json包实现了json对象的编解码,参见RFC 4627。Json对象和go类型的映射关系主要通过Marshal和Unmarshal函数实现

Marshal

func Marshal(v interface{}) ([]byte, error)

Marshal函数返回v的json编码。

Marshal函数会递归的处理值。如果一个值实现了Marshaler接口切非nil指针,会调用其MarshalJSON方法来生成json编码。nil指针异常并不是严格必需的,但会模拟与UnmarshalJSON的行为类似的必需的异常。

否则,Marshal函数使用下面的基于类型的默认编码格式:

布尔类型编码为json布尔类型。

浮点数、整数和Number类型的值编码为json数字类型。

字符串编码为json字符串。角括号"<"和">"会转义为"\u003c"和"\u003e"以避免某些浏览器吧json输出错误理解为HTML。基于同样的原因,"&"转义为"\u0026"。

数组和切片类型的值编码为json数组,但[]byte编码为base64编码字符串,nil切片编码为null。

结构体的值编码为json对象。每一个导出字段变成该对象的一个成员,除非:

  • 字段的标签是"-"
  • 字段是空值,而其标签指定了omitempty选项

    空值是false、0、""、nil指针、nil接口、长度为0的数组、切片、映射。对象默认键字符串是结构体的字段名,但可以在结构体字段的标签里指定。结构体标签值里的"json"键为键名,后跟可选的逗号和选项,举例如下:

// 字段被本包忽略

Field int json:"-"

// 字段在json里的键为"myName"

Field int json:"myName"

// 字段在json里的键为"myName"且如果字段为空值将在对象中省略掉

Field int json:"myName,omitempty"

// 字段在json里的键为"Field"(默认值),但如果字段为空值会跳过;注意前导的逗号

Field int json:",omitempty"

"string"选项标记一个字段在编码json时应编码为字符串。它只适用于字符串、浮点数、整数类型的字段。这个额外水平的编码选项有时候会用于和javascript程序交互:

Int64String int64 json:",string"

如果键名是只含有unicode字符、数字、美元符号、百分号、连字符、下划线和斜杠的非空字符串,将使用它代替字段名。

匿名的结构体字段一般序列化为他们内部的导出字段就好像位于外层结构体中一样。如果一个匿名结构体字段的标签给其提供了键名,则会使用键名代替字段名,而不视为匿名。

Go结构体字段的可视性规则用于供json决定那个字段应该序列化或反序列化时是经过修正了的。如果同一层次有多个(匿名)字段且该层次是最小嵌套的(嵌套层次则使用默认go规则),会应用如下额外规则:

1)json标签为"-"的匿名字段强行忽略,不作考虑;

2)json标签提供了键名的匿名字段,视为非匿名字段;

3)其余字段中如果只有一个匿名字段,则使用该字段;

4)其余字段中如果有多个匿名字段,但压平后不会出现冲突,所有匿名字段压平;

5)其余字段中如果有多个匿名字段,但压平后出现冲突,全部忽略,不产生错误。

对匿名结构体字段的管理是从go1.1开始的,在之前的版本,匿名字段会直接忽略掉。

映射类型的值编码为json对象。映射的键必须是字符串,对象的键直接使用映射的键。

指针类型的值编码为其指向的值(的json编码)。nil指针编码为null。

接口类型的值编码为接口内保持的具体类型的值(的json编码)。nil接口编码为null。

通道、复数、函数类型的值不能编码进json。尝试编码它们会导致Marshal函数返回UnsupportedTypeError。

Json不能表示循环的数据结构,将一个循环的结构提供给Marshal函数会导致无休止的循环。

Example

func json_encode() {
type ColorGroup struct {
ID int
Name string
Colors []string
}
group := ColorGroup{
ID: 1,
Name: "Reds",
Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
}
b, err := json.Marshal(group)
if err != nil {
fmt.Println("error:", err)
os.Exit(1)
} os.Stdout.Write(b)
}

Unmarshal

func Unmarshal(data []byte, v interface{}) error

Unmarshal函数解析json编码的数据并将结果存入v指向的值。

Unmarshal和Marshal做相反的操作,必要时申请映射、切片或指针,有如下的附加规则:

要将json数据解码写入一个指针,Unmarshal函数首先处理json数据是json字面值null的情况。此时,函数将指针设为nil;否则,函数将json数据解码写入指针指向的值;如果指针本身是nil,函数会先申请一个值并使指针指向它。

要将json数据解码写入一个结构体,函数会匹配输入对象的键和Marshal使用的键(结构体字段名或者它的标签指定的键名),优先选择精确的匹配,但也接受大小写不敏感的匹配。

要将json数据解码写入一个接口类型值,函数会将数据解码为如下类型写入接口:

Bool 对应JSON布尔类型

float64 对应JSON数字类型

string 对应JSON字符串类型

[]interface{} 对应JSON数组

map[string]interface{} 对应JSON对象

nil 对应JSON的null

如果一个JSON值不匹配给出的目标类型,或者如果一个json数字写入目标类型时溢出,Unmarshal函数会跳过该字段并尽量完成其余的解码操作。如果没有出现更加严重的错误,本函数会返回一个描述第一个此类错误的详细信息的UnmarshalTypeError。

JSON的null值解码为go的接口、指针、切片时会将它们设为nil,因为null在json里一般表示“不存在”。 解码json的null值到其他go类型时,不会造成任何改变,也不会产生错误。

当解码字符串时,不合法的utf-8或utf-16代理(字符)对不视为错误,而是将非法字符替换为unicode字符U+FFFD。

func json_decode() {
type ColorGroup struct {
ID int
Name string
Colors []string
}
group := ColorGroup{
ID: 1,
Name: "Reds",
Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
}
b, err := json.Marshal(group)
if err != nil {
fmt.Println("error:", err)
} r := ColorGroup{}
err = json.Unmarshal(b, &r)
if err != nil {
fmt.Println("json.Unmarshal error : ", err)
os.Exit(1)
} fmt.Println(r) }

处理json对象

json对象 通过 map[string]interface{} 表示

func json_struct_and_map() {

	type People struct {
Name string `json:"name"`
Age int `json:"age"`
Feature map[string]interface{} `json:feature`
} var feature map[string]interface{} = make(map[string]interface{})
feature["personality"] = "cute"
feature["Inner"] = "strength" p := People {
Name : "ailumiyana",
Age : 18,
Feature : feature,
} b, err := json.Marshal(p)
if err != nil {
fmt.Println("error:", err)
os.Exit(1)
} fmt.Println("encode : ")
os.Stdout.Write(b) r := People{}
err = json.Unmarshal(b, &r)
if err != nil {
fmt.Println("json.Unmarshal error : ", err)
os.Exit(1)
} fmt.Println("\ndecode : ")
fmt.Println(r) //update
if r.Feature == nil {
r.Feature = make(map[string]interface{})
}
r.Feature["fea"] = "warmth" b, err = json.Marshal(r)
if err != nil {
fmt.Println("error:", err)
os.Exit(1)
}
fmt.Println("update : ")
os.Stdout.Write(b)
}

完整示例 :

package main 

import(
"encoding/json"
"fmt"
"os"
) func json_encode() {
type ColorGroup struct {
ID int
Name string
Colors []string
}
group := ColorGroup{
ID: 1,
Name: "Reds",
Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
}
b, err := json.Marshal(group)
if err != nil {
fmt.Println("error:", err)
os.Exit(1)
} os.Stdout.Write(b)
} func json_decode() {
type ColorGroup struct {
ID int
Name string
Colors []string
}
group := ColorGroup{
ID: 1,
Name: "Reds",
Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
}
b, err := json.Marshal(group)
if err != nil {
fmt.Println("error:", err)
} r := ColorGroup{}
err = json.Unmarshal(b, &r)
if err != nil {
fmt.Println("json.Unmarshal error : ", err)
os.Exit(1)
} fmt.Println(r) } func json_struct_and_map() { type People struct {
Name string `json:"name"`
Age int `json:"age"`
Feature map[string]interface{} `json:feature`
} var feature map[string]interface{} = make(map[string]interface{})
feature["personality"] = "cute"
feature["Inner"] = "strength" p := People {
Name : "ailumiyana",
Age : 18,
Feature : feature,
} b, err := json.Marshal(p)
if err != nil {
fmt.Println("error:", err)
os.Exit(1)
} fmt.Println("encode : ")
os.Stdout.Write(b) r := People{}
err = json.Unmarshal(b, &r)
if err != nil {
fmt.Println("json.Unmarshal error : ", err)
os.Exit(1)
} fmt.Println("\ndecode : ")
fmt.Println(r) //update
if r.Feature == nil {
r.Feature = make(map[string]interface{})
}
r.Feature["fea"] = "warmth" b, err = json.Marshal(r)
if err != nil {
fmt.Println("error:", err)
os.Exit(1)
}
fmt.Println("update : ")
os.Stdout.Write(b)
} func main(){
json_encode()
json_decode() json_struct_and_map() }

go笔记--json包使用的更多相关文章

  1. nodejs学习笔记之包、模块实现

        简单了解了node的安装和一些基本的常识之后,今天学习了node中很重要的包和模块的一些知识点.       首先学习一下包的规范,它由包结构和包描述两部分组成.包结构用于组织包的各种文件,包 ...

  2. Java创建和解析Json数据方法(二)——org.json包的使用

    (二)org.json包的使用 1.简介   工具包org.json.jar,是一个轻量级的,JAVA下的json构造和解析工具包,它还包含JSON与XML, HTTP headers, Cookie ...

  3. Java创建和解析Json数据方法——org.json包的使用(转)

    org.json包的使用 1.简介   工具包org.json.jar,是一个轻量级的,JAVA下的json构造和解析工具包,它还包含JSON与XML, HTTP headers, Cookies, ...

  4. WP8如何添加Newtonsoft.Json包

    WP8开发的时候如何使用Newtonsoft.Json包呢?我在网上包括官网下的DLL文件,添加引用时都给出了这样的提示: 而后在网上找到的解决办法是:使用NuGet程序包来添加. 首先点击工具--& ...

  5. TJI读书笔记14-闭包与回调

      TJI读书笔记14-闭包与回调 闭包与回调 为什么要使用内部类?内部类继承自某个类或者实现某个接口,内部类的代码可以操作外嵌类的对象. 这不是使用内部类的理由. 那么为什么使用内部类呢? 我觉得如 ...

  6. golang json 包简单分析

    首先上代码: func main() { b := true a1, _ := json.Marshal(b) a2, _ := Marshal(b) fmt.Println(string(a1)) ...

  7. 两层嵌套的JSON包的解法

    由于后台的变态,有时候会出现两层甚至多层嵌套的JSON包. 一层的很好解,而且我看过一些比较大的网站新闻接口返回的JSON包也仅仅是一层的. 比如下图所示一层的包 代码也很简单直观 dict = [d ...

  8. Java中net.sf.json包关于JSON与对象互转的问题

    在Web开发过程中离不开数据的交互,这就需要规定交互数据的相关格式,以便数据在客户端与服务器之间进行传递.数据的格式通常有2种:1.xml:2.JSON.通常来说都是使用JSON来传递数据.本文正是介 ...

  9. Java中net.sf.json包关于JSON与对象互转的坑

    在Web开发过程中离不开数据的交互,这就需要规定交互数据的相关格式,以便数据在客户端与服务器之间进行传递.数据的格式通常有2种:1.xml:2.JSON.通常来说都是使用JSON来传递数据.本文正是介 ...

随机推荐

  1. git 使用详解 (1)——历史

    版本控制系统(VCS) 有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态.你可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而导致出现怪异问题,又是谁在何时报 ...

  2. 线性规划VB求解

    线性规划VB求解 Rem 定义动态数组 Dim a() As Single, c() As Single, b() As Single, cb() As Single Dim aa() As Sing ...

  3. Zabbix通过与微信、钉钉整合实现实时告警

    abbix可以通过多种方式把告警信息发送到指定人,常用的有邮件,短信报警方式,但是越来越多的企业开始使用zabbix结合微信.钉钉作为主要的告警方式,这样可以及时有效的把告警信息推送到接收人,方便告警 ...

  4. JavaScript 逻辑与(&&) 与 逻辑或(||) 运算规则

    逻辑与(&&) 逻辑与(&&)操作可以应用于任何的操作类型,不仅仅是布尔值, 在有一个操作数不是布尔值的情况下,&&操作符就不一定返回布尔值:遵循下面规 ...

  5. Flume理论研究与实验

    一.理论研究 1.1 总览 Flume是一个分布式的可靠的日志收集系统,主要是用于从各种数据源收集.聚合并移动大批量的日志数据到存储系统:它本身具有许多故障转移和恢复机制,具有强大的容错能力:它使用下 ...

  6. 使用 yum 安装Docker(CentOS 7下)

    使用 yum 安装(CentOS 7下) Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker . 通过 uname ...

  7. Java获取配置文件中的属性

    获取配置文件的属性值 example 目标配置文件jdbc.properties,现想要在java类里面调用opcl的url jdbc.url=jdbc:mysql://localhost:3306/ ...

  8. 我的第一次面试 —— 腾讯 AI安全 一面总结

    前言 在校两年半,没经历过面试的毒打,第一次面试给了腾讯,周二晚上学长帮推的简历周三下午就打电话来问周四晚上有没有空面试.那天下午还在赶着数据库的实验报告,脑子有点转不过来就说了有空,然后仔细一看好像 ...

  9. C# read file to bytes,File.ReadAllFiles,File.Open(),BinaryReader

    using System; using System.Text; using System.IO; namespace ConsoleApplication15 { class Program { s ...

  10. 小程序填坑——bindconfirm事件

    一.介绍 当你要在手机软键盘中触发一些方法,就可以使用input标签的bindconfirm事件.这个事件的作用是当你在软键盘上点击确认的时候,将触发你指定的方法. 还可以使用confirm-type ...