json 解析:marshal 和 unmarshal
Go 使用 encoding/json 包的 marshal 和 unmarshal 实现 json 数据的编解码。分别记录如下:
1. marshal
定义结构体:
type OCP struct {
Name string `json:"name"`
ImageRegistry *ImageRegistry `json:"imageRegistry"`
Status string `json:"status"`
Events []string `json:"events"`
id *int
}
type ImageRegistry struct {
Addr string `json:"addr"`
User string `json:"user"`
Password string `json:"password"`
}
将结构体 OCP 类型值编码成 json 格式:
func main() {
imageRegistry := ImageRegistry{
Addr: "x.x.x.x",
User: "admin",
Password: "admin",
}
ocp := OCP{
Name: "lubanseven",
ImageRegistry: &imageRegistry,
Status: "running",
Events: []string{"normal", "normal", "normal"},
}
data, err := json.Marshal(ocp)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(data))
}
输出:
{"name":"lubanseven","imageRegistry":{"addr":"x.x.x.x","user":"admin","password":"admin"},"status":"running","events":["normal","normal","normal"]}
从输出可以看出:
- 结构体中以小写字母开头的类型(id)不会被编码。
- 结构体中指针类型在编码时将转换为指针所指向的值。
更多编码规则可看 JSON and Go
2. unmarshal
类似的将 data 解码为结构体类型 OCP 的值:
var lubanseven OCP
err = json.Unmarshal(data, &lubanseven)
if err != nil {
fmt.Println(err)
}
fmt.Println(lubanseven)
输出:
{lubanseven 0xc00020e360 running [normal normal normal] <nil>}
从输出可以看出:
- 指针类型的值在解码时将转换为值的地址。
- 对于无法解码的值,将转换为该值的零值,如指针类型变量 id 解码为 nil。
更多编码规则可看 JSON and Go
对于第二点,将 id 类型定义成 int,查看解码后的结构体值:
type OCP struct {
Name string `json:"name"`
ImageRegistry *ImageRegistry `json:"imageRegistry"`
Status string `json:"status"`
Events []string `json:"events"`
id int
}
输出:
{lubanseven 0xc0000cc4b0 running [normal normal normal] 0}
这点在解码的时候要注意。
上例中解码的结构体类型是已知的,如果结构体未知该如何确定结构体类型呢?这在实际场景中是会发生的,比如传输的数据流,事先不知道其结构体类型。
可以通过类型断言的方式,确定结构体类型,如下:
var lubanunknown interface{}
err = json.Unmarshal(data, &lubanunknown)
if err != nil {
fmt.Println(err)
}
fmt.Println(lubanunknown)
if value, ok := lubanunknown.(map[string]interface{}); ok {
fmt.Println(value)
}
输出:
map[events:[normal normal normal] imageRegistry:map[addr:x.x.x.x password:admin user:admin] name:lubanseven status:running]
map[events:[normal normal normal] imageRegistry:map[addr:x.x.x.x password:admin user:admin] name:lubanseven status:running]
输出类型是 map[string]interface{},key 是 string,value 是 interface{},可以对 value 进行类型断言确定 interface{} 的实质类型(直接看输出也能看出来...):
value := lubanunknown.(map[string]interface{})
for k, v := range value {
switch vv := v.(type) {
case int:
fmt.Println(k, "is int: ", vv)
case string:
fmt.Println(k, "is string: ", vv)
case []interface{}:
fmt.Println(k, "is slice: ", vv)
for _, v := range vv {
fmt.Println(v)
}
case map[string]interface{}:
fmt.Println(k, "is struct: ", vv)
default:
fmt.Println(k, "unexpect type of ", reflect.TypeOf(vv))
}
}
输出:
imageRegistry is struct: map[addr:x.x.x.x password:admin user:admin]
status is string: running
events is slice: [normal normal normal]
normal
normal
normal
name is string: lubanseven
3. 数据流的 json 编解码
对数据流的编解码,如下:
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)
}
}
}
示例来自 JSON and Go
运行示例:
$ go run main.go
{"name":"lubanseven","imageRegistry":{"addr":"x.x.x.x","user":"admin","password":"admin"},"status":"running","events":["normal","normal","normal"]}
{}
{"Name":"lubanseven","imageRegistry":{"addr":"x.x.x.x","user":"admin","password":"admin"},"status":"running","events":["normal","normal","normal"]}
{"Name":"lubanseven"}
json 解析:marshal 和 unmarshal的更多相关文章
- go json解析Marshal和Unmarshal
Decoder: package main import ( "encoding/json" "fmt" "io" "log&qu ...
- golang struct 定义中json``解析说明
在代码学习过程中,发现struct定义中可以包含`json:"name"`的声明,所以在网上找了一些资料研究了一下 package main import ( "enco ...
- go语言之进阶篇json解析到map
1.json解析到map(通过类型断言,找到值和value类型) 示例: package main import ( "encoding/json" "fmt" ...
- go语言之进阶篇json解析到结构体
1.json解析到结构体 示例: package main import ( "encoding/json" "fmt" ) type IT struct { ...
- [GO]json解析到map
package main import ( "encoding/json" "fmt" ) var str string func main() { m := ...
- 深入 Go 中各个高性能 JSON 解析库
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/535 其实本来我是没打算去看 JSON 库的性能问题的,但是最近我对 ...
- 【golang】json数据解析 - 嵌套json解析
@ 目录 1. 通过结构体映射解析 2. 嵌套json解析-map 1. 通过结构体映射解析 原数据结构 解析 // 结构体 type contractJson struct { Data []tra ...
- Android okHttp网络请求之Json解析
前言: 前面两篇文章介绍了基于okHttp的post.get请求,以及文件的上传下载,今天主要介绍一下如何和Json解析一起使用?如何才能提高开发效率? okHttp相关文章地址: Android o ...
- Json解析工具的选择
前言 前段时间@寒江不钓同学针对国内Top500和Google Play Top200 Android应用做了全面的分析(具体分析报告见文末的参考资料),其中有涉及到对主流应用使用json框架Gson ...
- iOS json 解析遇到error: Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed.
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 38 ...
随机推荐
- JQuery_1
1.概念:一个JavaScript框架.简化js开发 JavaScript框架:本质上就是一些js文件,封装了js的原生代码. 2.快速入门: 1.步骤 1.下载JQuery jquery.xxx.j ...
- 配置tabBar导航菜单与open跳转差异
"tabBar": { "color": "#333", "selectedColor": ...
- Git提交修正
应用场景 日常开发中我们可能会遇到这样的问题 1.提交了代码有错误 2.提交的信息写错了 3.漏了一些文件没有提交 ...... 再或者我们写一个功能时,中间有很多小的提交,这中间就会产生特别多的co ...
- C++ Qt开发:自定义Dialog对话框组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍自定义Dial ...
- Salesforce LWC学习(四十七) 标准页面更新以后自定义页面如何捕捉?
本篇参考: https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platfor ...
- GPT-4多模态大型语言模型发布
GPT-4 模型是OpenAI开发的第四代大型语言模型(LLM),它将是一个多模态模型,会提供完全不同的可能性-例如文字转图像.音乐甚至视频.GPT 全称为 Generative Pre-traine ...
- Python——第三章:内置函数(上)
Python中的内置函数 基础数据类型相关(38) 和数字相关(14) 数字类型(4) bool--布尔型 int--整型 float--浮点型 complex--虚数 机制转换(3) bin--二进 ...
- 数据结构入门之单链表代码实现(java)
1:单链表是: 单链表是一种链式存取的 数据结构 用一组地址任意的 存储单元 存放线性表中的数据元素. 链表中的数据是以结点来表示的,每个结点的构成:元素 ( 数据元素 的映象) + 指针 (指示后继 ...
- 华为API战略:规范、组织和流程驱动企业大循环
摘要:构建一套完善的API规范流程体系变得至关重要,用方法论驱动整个API变革,用API变革驱动共享经济模式,以共享模式反推数字化转型. 本文分享自华为云社区<API战略--华为在数字化浪潮下的 ...
- 带你认识MindSpore量子机器学习库MindQuantum
摘要:MindSpore在3.28日正式开源了量子机器学习库MindQuantum,本文介绍MindQuantum的关键技术. 本文分享自华为云社区<MindSpore量子机器学习库MindQu ...