go笔记--json包使用
@
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包使用的更多相关文章
- nodejs学习笔记之包、模块实现
简单了解了node的安装和一些基本的常识之后,今天学习了node中很重要的包和模块的一些知识点. 首先学习一下包的规范,它由包结构和包描述两部分组成.包结构用于组织包的各种文件,包 ...
- Java创建和解析Json数据方法(二)——org.json包的使用
(二)org.json包的使用 1.简介 工具包org.json.jar,是一个轻量级的,JAVA下的json构造和解析工具包,它还包含JSON与XML, HTTP headers, Cookie ...
- Java创建和解析Json数据方法——org.json包的使用(转)
org.json包的使用 1.简介 工具包org.json.jar,是一个轻量级的,JAVA下的json构造和解析工具包,它还包含JSON与XML, HTTP headers, Cookies, ...
- WP8如何添加Newtonsoft.Json包
WP8开发的时候如何使用Newtonsoft.Json包呢?我在网上包括官网下的DLL文件,添加引用时都给出了这样的提示: 而后在网上找到的解决办法是:使用NuGet程序包来添加. 首先点击工具--& ...
- TJI读书笔记14-闭包与回调
TJI读书笔记14-闭包与回调 闭包与回调 为什么要使用内部类?内部类继承自某个类或者实现某个接口,内部类的代码可以操作外嵌类的对象. 这不是使用内部类的理由. 那么为什么使用内部类呢? 我觉得如 ...
- golang json 包简单分析
首先上代码: func main() { b := true a1, _ := json.Marshal(b) a2, _ := Marshal(b) fmt.Println(string(a1)) ...
- 两层嵌套的JSON包的解法
由于后台的变态,有时候会出现两层甚至多层嵌套的JSON包. 一层的很好解,而且我看过一些比较大的网站新闻接口返回的JSON包也仅仅是一层的. 比如下图所示一层的包 代码也很简单直观 dict = [d ...
- Java中net.sf.json包关于JSON与对象互转的问题
在Web开发过程中离不开数据的交互,这就需要规定交互数据的相关格式,以便数据在客户端与服务器之间进行传递.数据的格式通常有2种:1.xml:2.JSON.通常来说都是使用JSON来传递数据.本文正是介 ...
- Java中net.sf.json包关于JSON与对象互转的坑
在Web开发过程中离不开数据的交互,这就需要规定交互数据的相关格式,以便数据在客户端与服务器之间进行传递.数据的格式通常有2种:1.xml:2.JSON.通常来说都是使用JSON来传递数据.本文正是介 ...
随机推荐
- 挑战10个最难的Java面试题(附答案)【上】【华为云技术分享】
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/devcloud/article/deta ...
- Java语法进阶13-文件、IO流
File File是文件和目录路径名的抽象表示形式,即File类是文件或目录的路径,而不是文件本身,因此File类不能直接访问文件内容本身,如果需要访问文件内容本身,则需要使用输入/输出流. File ...
- Java学习笔记(面向对象下)
面向对象(下) 类的继承 类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类称为子类,现有类称为父类,子类会自动拥有父类所有可继承的属性和方法.(用extends关键字) //定义A ...
- HDU1848 Fibonacci again and again(SG 函数)
任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的: F(1)=1; F(2)=2; F(n)=F(n-1)+F(n-2)(n>=3); 所以,1, ...
- MFC unicode字符集与多字节字符集 问题之彻底终结!
Unicode 和多字节字符集 (MBCS) 支持 Visual Studio .NET 2003 有些国际市场以大字符集来使用日文和中文等语言.为了支持这些市场的编程,Microsoft 基础类 ...
- 每周一练 之 数据结构与算法(Stack)
最近公司内部在开始做前端技术的技术分享,每周一个主题的 每周一练,以基础知识为主,感觉挺棒的,跟着团队的大佬们学习和复习一些知识,新人也可以多学习一些知识,也把团队内部学习氛围营造起来. 我接下来会开 ...
- Flume理论研究与实验
一.理论研究 1.1 总览 Flume是一个分布式的可靠的日志收集系统,主要是用于从各种数据源收集.聚合并移动大批量的日志数据到存储系统:它本身具有许多故障转移和恢复机制,具有强大的容错能力:它使用下 ...
- 【MySql】使用学习
[MySql]使用学习 =================================================== 1.太多的连接 Too many connections ======= ...
- 201871010119-帖佼佼《面向对象程序设计(java)》第一周学习总结
项目 内容 这个作业属于哪个课程 <任课教师博客主页链接> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址> ...
- haproxy 在centos上cannot bind 端口的问题
setsebool -P haproxy_connect_any=1 要不把selinux干掉也行