go标准库的学习-encoding/json
参考https://studygolang.com/pkgdoc
导入方式:
import "encoding/json"
json包实现了json对象的编解码,参见RFC 4627。Json对象和go类型的映射关系请参见Marshal和Unmarshal函数的文档。
参见"JSON and Go"获取本包的一个介绍:http://golang.org/doc/articles/json_and_go.html
func 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。
举例:通过interface{} 与 type assert的配合,这样就能够解析未知结构的JSON数了
package main
import(
"fmt"
"encoding/json"
) func main() {
var s interface{}
str := `
{
"name" : "testJSON",
"servers" : [
{
"serverName" : "Shanghai_VPN",
"serverIP" : "127.0.0.1"
},
{
"serverName" : "Beijing_VPN",
"serverIP" : "127.0.0.2"
}
],
"status" : false
}`
json.Unmarshal([]byte(str), &s)
fmt.Println(s)
//然后需要通过断言来将其从interface{}类型转成map[string]interface{}类型
m := s.(map[string]interface{}) for key, value := range m {
switch v := value.(type){//得到s的类型
case string :
fmt.Println(key , " is string ", v)
case int :
fmt.Println(key, "is int", v)
case []interface{}:
fmt.Println(key, "is an array")
for i, vv := range v{
fmt.Println(i, vv)
}
default:
fmt.Println(key, "is of a type i don't know how to handle")
}
}
}
返回:
userdeMBP:go-learning user$ go run test.go
map[name:testJSON servers:[map[serverName:Shanghai_VPN serverIP:127.0.0.1] map[serverName:Beijing_VPN serverIP:127.0.0.2]] status:false]
name is string testJSON
servers is an array
0 map[serverName:Shanghai_VPN serverIP:127.0.0.1]
1 map[serverIP:127.0.0.2 serverName:Beijing_VPN]
status is of a type i don't know how to handle
func 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函数会导致无休止的循环。
func MarshalIndent
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
MarshalIndent类似Marshal但会使用缩进将输出格式化。其可读性更高
package main
import(
"fmt"
"encoding/json"
"os"
)
type Address struct {
City, State string
}
type Person struct {
Id int `json:"id"` //id作为该JSON字段的key值
FirstName string //不设置标签则默认使用FirstName为字段key值
LastName string `json:"-"` //字段被本包忽略,即使有值也不输出
Age int `json:",omitempty"` //含omitempty选项的字段如果为空值会省略,如果存在Age作为该JSON字段的key值
Height float32 `json:"height,omitempty"` //含omitempty选项的字段如果为空值会省略,如果存在height作为该JSON字段的key值
Address //匿名字段(其标签无效)会被处理为其字段是外层结构体的字段,所以没有Address这个元素,而是直接显示City, State这两个元素
} func main() {
v := &Person{Id: , FirstName: "John", LastName: "Doe", Age: }
v.Address = Address{"Hanga Roa", "Easter Island"}
output, err := json.MarshalIndent(v, "&", " ")//每行以&作为前缀,并缩进四个空格
if err != nil {
fmt.Printf("error: %v\n", err)
}
os.Stdout.Write(output)
}
返回:
userdeMBP:go-learning user$ go run test.go
{
& "id": ,
& "FirstName": "John",
& "Age": ,
& "City": "Hanga Roa",
& "State": "Easter Island"
&}
如果使用的是Marshal,则返回:
userdeMBP:go-learning user$ go run test.go
{"id":,"FirstName":"John","Age":,"City":"Hanga Roa","State":"Easter Island"}
未完待续
go标准库的学习-encoding/json的更多相关文章
- go标准库的学习-encoding/base64
参考:https://studygolang.com/pkgdoc 导入方式: import "encoding/base64" base64实现了RFC 4648规定的base6 ...
- go标准库的学习-encoding/xml
参考:https://studygolang.com/pkgdoc 导入方式: import "encoding/xml" 实现的简单的理解XML命名空间的XML 1.0编译器 f ...
- go标准库的学习-net/http
参考:https://studygolang.com/pkgdoc 概念解释: request:用户请求的信息,用来解析用户的请求信息,包括post.get.cookie.url等信息 respons ...
- go标准库的学习-database/sql
参考:https://studygolang.com/pkgdoc 导入方式: import "database/sql" sql包提供了保证SQL或类SQL数据库的泛用接口. 使 ...
- go标准库的学习-crypto/md5
参考:https://studygolang.com/pkgdoc 导入方式: import "crypto/md5" md5包实现了MD5哈希算法,参见RFC 1321. Con ...
- go标准库的学习-crypto/sha1
参考:https://studygolang.com/pkgdoc 导入方式: import "crypto/sha1" sha1包实现了SHA1哈希算法,参见RFC 3174. ...
- go标准库的学习-crypto/sha256
参考:https://studygolang.com/pkgdoc 导入方式: import "crypto/sha256" sha256包实现了SHA224和SHA256哈希算法 ...
- python 标准库基础学习之开发工具部分1学习
#2个标准库模块放一起学习,这样减少占用地方和空间#标准库之compileall字节编译源文件import compileall,re,sys#作用是查找到python文件,并把它们编译成字节码表示, ...
- python calendar标准库基础学习
# -*- coding: utf-8 -*-# 作者:新手__author__ = 'Administrator'#标准库:日期时间基础学习:calendar:处理日期#例1import calen ...
随机推荐
- WPF Application 类介绍以及怎样修改启动方式
因为想要修改wpf的启动方式,所以研究了下Application类,现把一些有用的属性与大家分享下: 属性: Current 获取当前 AppDomain的 Appl ...
- spring cloud config服务器
Spring Cloud Config提供了一种在分布式系统中外部化配置服务器和客户端的支持.配置服务器有一个中心位置,管理所有环境下的应用的外部属性.客户端和服务器映射到相同Spring Event ...
- 如何在 ASP.NET Core 测试中操纵时间?
有时候,我们会遇到一些跟系统当前时间相关的需求,例如: 只有开学季才允许录入学生信息 只有到了晚上或者周六才允许备份博客 注册满 3 天的用户才允许进行一些操作 某用户在 24 小时内被禁止发言 很显 ...
- SVN多项目并行版本管理解决方案
1.背景 随着公司业务拓展,各业务部门频繁的需求变更,导致系统集成冲突的问题日益突出. 2.现状 基于SVN版本管理模式,多分支版本并行,分支合并主干交付.多分支开发存在依赖关系且有交付的先后顺序, ...
- CSS布局设置
一 盒模型 盒模型 在CSS中,"box model"这一术语是用来设计和布局时使用,然后在网页中基本上都会显示一些方方正正的盒子.我们称为这种盒子叫盒模型. 盒模型有两种:标准模 ...
- css清除默认样式
CSS 清除默认样式 通常有以下几句就够了: *{margin:0;padding:0} li{list-style:none} img{vertical-align:top;border:non ...
- 【详细】【转】CentOS 7部署ASP.NET Core应用程序
很早就看过关于net core部署在Linux上的文章,自己也曾亲自将项目部署在Linux上,今天看到这篇文章,为其格式之工整而转! 1.环境准备 网上看了一下,Linux云服务器还挺贵的,那就只好先 ...
- (网页)the server responded with a status of 403 (Forbidden)
403跨域问题.看一下要访问的url.
- gitlab-ci的注意点
在使用gitlab搭配gitlab-runner进行ci配置时,发现两个问题,略记如下备忘: 1. 若发现ci job控制台显示无法下载该项目,但当前提交代码人和ci用户都确实具备该项目的访问权限时, ...
- LeetCode题解之Second Minimum Node In a Binary Tree
1.题目描述 2.问题分析 使用set. 3.代码 set<int> s; int findSecondMinimumValue(TreeNode* root) { dfs(root); ...