@


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. 在modelarts上部署mask-rcnn模型

    最近老山完成了对mask-rcnn在modelarts上的部署,部署模型来自于这个项目.部署的过程大体和我的上篇文章使用modelarts部署bert命名实体识别模型相似,许多细节也不在赘述.这篇文章 ...

  2. c获取shell中的参数

    问题背景 在Linux中我们会使用到shell,来完成输入参数的获取,就如同下面的形式,这种形式在进行多语言编程和调用有着非常重要的作用 一.传递的过程 1.1 原理模型如下: 1.1.1 可执行sh ...

  3. luogu P2345 奶牛集会 |排序+树状数组

    题目描述 约翰的N 头奶牛每年都会参加"哞哞大会".哞哞大会是奶牛界的盛事.集会上的活动很多,比如堆干草,跨栅栏,摸牛仔的屁股等等.它们参加活动时会聚在一起,第i 头奶牛的坐标为X ...

  4. C# 设置、删除、读取Word文档背景——基于Spire.Cloud.Word

    Spire.Cloud.Word.Sdk提供了接口SetBackgroudColor().SetBackgroudImage().DeleteBackground().GetBackgroudColo ...

  5. ios instancetype与id区别

    我们都知道未知类型的的对象可以用id关键字表示,那为什么还会再有一个instancetype呢? instancetype能返回相关联的类型(使那些非关联返回类型的方法返回所在类的类型):而id 返回 ...

  6. Node.js 中 __dirname 和 ./ 的区别

    概要 __dirname 总是指向被执行 js 文件的绝对路径 在 /d1/d2/myscript.js 文件中写了 __dirname, 它的值就是 /d1/d2 . ./ 会返回你执行 node ...

  7. ACM-ICPC 2018 焦作赛区网络预赛 K题 Transport Ship

    There are NN different kinds of transport ships on the port. The i^{th}ith kind of ship can carry th ...

  8. Python发送邮件以及对其封装

    对Python发送邮件进行封装 Python发送邮件分为四步 连接到smtp服务器 登陆smtp服务器 准备邮件 发送邮件 导入所需要的包 import smtplib from email.mime ...

  9. 【Selenium】自动进入网页,出现弹窗被卡住

    问题现象: 使用命令:driver.get("http://127.0.0.1/zentao/user-login.html") 进入网页,出现如下弹窗,无法进入 解决方法: #d ...

  10. Spring Integration - WS Outbound Gateway

    1.通过MessageSender客户化http连接参数 AbstractHttpWebServiceMessageSender有若干实现子类: - CommonsHttpMessageSender( ...