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"]}

从输出可以看出:

  1. 结构体中以小写字母开头的类型(id)不会被编码。
  2. 结构体中指针类型在编码时将转换为指针所指向的值。

更多编码规则可看 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>}

从输出可以看出:

  1. 指针类型的值在解码时将转换为值的地址。
  2. 对于无法解码的值,将转换为该值的零值,如指针类型变量 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的更多相关文章

  1. go json解析Marshal和Unmarshal

    Decoder: package main import ( "encoding/json" "fmt" "io" "log&qu ...

  2. golang struct 定义中json``解析说明

    在代码学习过程中,发现struct定义中可以包含`json:"name"`的声明,所以在网上找了一些资料研究了一下 package main import ( "enco ...

  3. go语言之进阶篇json解析到map

    1.json解析到map(通过类型断言,找到值和value类型) 示例: package main import ( "encoding/json" "fmt" ...

  4. go语言之进阶篇json解析到结构体

    1.json解析到结构体 示例: package main import ( "encoding/json" "fmt" ) type IT struct { ...

  5. [GO]json解析到map

    package main import ( "encoding/json" "fmt" ) var str string func main() { m := ...

  6. 深入 Go 中各个高性能 JSON 解析库

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/535 其实本来我是没打算去看 JSON 库的性能问题的,但是最近我对 ...

  7. 【golang】json数据解析 - 嵌套json解析

    @ 目录 1. 通过结构体映射解析 2. 嵌套json解析-map 1. 通过结构体映射解析 原数据结构 解析 // 结构体 type contractJson struct { Data []tra ...

  8. Android okHttp网络请求之Json解析

    前言: 前面两篇文章介绍了基于okHttp的post.get请求,以及文件的上传下载,今天主要介绍一下如何和Json解析一起使用?如何才能提高开发效率? okHttp相关文章地址: Android o ...

  9. Json解析工具的选择

    前言 前段时间@寒江不钓同学针对国内Top500和Google Play Top200 Android应用做了全面的分析(具体分析报告见文末的参考资料),其中有涉及到对主流应用使用json框架Gson ...

  10. 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 ...

随机推荐

  1. JQuery_1

    1.概念:一个JavaScript框架.简化js开发 JavaScript框架:本质上就是一些js文件,封装了js的原生代码. 2.快速入门: 1.步骤 1.下载JQuery jquery.xxx.j ...

  2. 配置tabBar导航菜单与open跳转差异

    "tabBar": {        "color": "#333",        "selectedColor": ...

  3. Git提交修正

    应用场景 日常开发中我们可能会遇到这样的问题 1.提交了代码有错误 2.提交的信息写错了 3.漏了一些文件没有提交 ...... 再或者我们写一个功能时,中间有很多小的提交,这中间就会产生特别多的co ...

  4. C++ Qt开发:自定义Dialog对话框组件

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍自定义Dial ...

  5. Salesforce LWC学习(四十七) 标准页面更新以后自定义页面如何捕捉?

    本篇参考: https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platfor ...

  6. GPT-4多模态大型语言模型发布

    GPT-4 模型是OpenAI开发的第四代大型语言模型(LLM),它将是一个多模态模型,会提供完全不同的可能性-例如文字转图像.音乐甚至视频.GPT 全称为 Generative Pre-traine ...

  7. Python——第三章:内置函数(上)

    Python中的内置函数 基础数据类型相关(38) 和数字相关(14) 数字类型(4) bool--布尔型 int--整型 float--浮点型 complex--虚数 机制转换(3) bin--二进 ...

  8. 数据结构入门之单链表代码实现(java)

    1:单链表是: 单链表是一种链式存取的 数据结构 用一组地址任意的 存储单元 存放线性表中的数据元素. 链表中的数据是以结点来表示的,每个结点的构成:元素 ( 数据元素 的映象) + 指针 (指示后继 ...

  9. 华为API战略:规范、组织和流程驱动企业大循环

    摘要:构建一套完善的API规范流程体系变得至关重要,用方法论驱动整个API变革,用API变革驱动共享经济模式,以共享模式反推数字化转型. 本文分享自华为云社区<API战略--华为在数字化浪潮下的 ...

  10. 带你认识MindSpore量子机器学习库MindQuantum

    摘要:MindSpore在3.28日正式开源了量子机器学习库MindQuantum,本文介绍MindQuantum的关键技术. 本文分享自华为云社区<MindSpore量子机器学习库MindQu ...