我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Go结构体序列化的实现是怎样的

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Go结构体序列化的实现是怎样的

Go结构体序列化的实现是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

我们将回到之前写的showMovieHandler方法,并更新它以返回一个JSON响应,表示系统中的单个电影信息。类似于:

{    "id": 123,    "title": "Casablanca",     "runtime": 102,     "genres": [        "drama",         "romance",         "war"    ],    "version": 1 }

我们不使用map序列化来创建这个JSON对象(就像我们在上一节中所做的那样),这次我们将编码一个自定义的Movie结构体。

首先,需要定义一个Movie结构体。我们将在一个新internal/data包中完成此操作,该包稍后将扩展用来封装项目中所有自定义数据类型以及与数据库交互的逻辑。

如果您按照文章步骤操作,请创建一个新的internal/data目录,其中包含一个movies.go文件:

$ mkdir internal/data$ touch internal/data/movies.go

在这个新文件中,定义Movie结构,像这样:

File: internal/data/movies.go

package mainimport (    "time")type Movie struct {    ID             int64      //唯一整数ID    CreatedAt      time.Time  //创建电影到数据库的时间    Title          string     //电影标题    Year           int32      //电影发布年份    Runtime        int32      //电影时长    Genres         []string   //电影类型(爱情片、喜剧片等)    Version        int32      //版本号从1开始,每更新一次递增}

这里需要指出的是,Movie结构体中的所有字段都是可导出的(即以大写字母开头),这对于Go的encoding/json包可见是必要的。在将结构体编码为JSON时,不会包含任何未导出的字段。

现在结构体已经定义完成,让我们更新showMovieHandler处理程序来初始化一个Movie结构体实例,然后使用writeJSON()帮助函数将其作为JSON响应发送给客户端。

实现很简单:

File: cmd/api/movies.go

package mainimport (    "fmt"    "net/http"    "time"    "greenlight.alexedwards.net/internal/data")func (app *application) showMovieHandler(w http.ResponseWriter, r *http.Request) {    id, err := app.readIDParam(r)    if err != nil {        http.NotFound(w, r)        return    }    //创建一个Move结构体实例,包含从请求URL中解析的ID虚构的数据。注意这里故意没有设置Year字段    movie := date.Movie{        ID: id,        CreateAt: time.now(),        Title: "Casablanca",        Runtime: 102,        Genres: []string{"drama", "romance", "war"},        Version: 1,    }    //将结构体序列化为JSON并以HTTP响应发送给客户端    err = app.writeJSON(w, http.StatusOK, movie, nil)    if err != nil {         app.logger.Println(err)         http.Error(w, "The server encountered a problem and could not process your request", http.StatusInternalServerError)    }}

ok,下面试试!

重启API,然后在浏览器中访问localhost:4000/v1/movies/123。你应该会看到一个类似这样的JSON响应:

Go结构体序列化的实现是怎样的

在这个返回结果中,有几件有趣的事情需要指出:

  • Movie结构体被编码成一个JSON对象,字段名和值作为键/值对。

  • 默认情况下,JSON对象中的键等于结构体中的字段名(ID、CreatedAt、Title等等)。我们稍后将讨论如何自定义JSON键。

  • 如果结构体实例字段没有显式赋值,那么字段零值将序列化为json值。可以在上面的响应中看到——我们没有在Go代码中为Year字段设置值,但它仍然以0值出现在JSON输出中。

更改JSON对象中的键

在Go中序列化结构体的一个好处是,您可以通过使用struct标签注释字段来定制JSON。

struct标签最常见的用途可能是更改JSON对象中出现的键名称。当你的结构体字段名不适合面向公众展示,或者你想在JSON输出中使用另一种大小写样式时,这是很有用的。

为了说明如何实现,对Movies结构体字段打标签,使用蛇形格式:

File: internal/data/movies.go

//使用标记对Movie结构进行注释,以控制json编码的key显示方式。type Movie struct {    ID       int64     `json:"id"`    CreateAt time.Time `json:"created_at"`    Title    string    `json:"title"`    Year     int32     `json:"year"`    Runtime  int32     `json:"runtime"`    Genres   []string  `json:"genres"`    Version  int32     `json:"version"`}

如果你重启服务器并再次访问localhost:4000/v1/movies/123,应该会看到一个类似于这样的带有蛇形键的响应:

Go结构体序列化的实现是怎样的

在JSON对象中隐藏结构体字段

在定义结构体时候,通过使用omitempty可以控制对应字段在JSON中的可见性。当您不希望JSON输出中出现特定的结构体字段时,可以使用-(连字符)指令。这对包含和用户不相关的内部系统信息的字段或不想公开的敏感信息(如密码哈希值)非常有用。

相反,当且仅当struct字段值为空时,omitempty指令会在JSON输出中隐藏字段,其中empty被定义为:

  • 等于false,0或“”

  • 空数组,切片或map

  • nil指针或接口值为nil

为了演示如何使用这些指令,我们对Movie结构进行更多的改造。CreatedAt字段与我们的最终用户无关,所以我们使用-指令在输出中将其隐藏。我们还将使用omitempty指令在输出中隐藏Year、Runtime和types字段,当且仅当它们为空时生效。

继续并像下面这样更新struct标签:

File:interface/data/movies.go

package data....type Movie struct {    ID       int64     `json:"id"`    CreateAt time.Time `json:"-"`       //使用-指令    Title    string    `json:"title"`    Year     int32     `json:"year,omitempty"`            //添加omitempty    Runtime  int32     `json:"runtime,omitempty"`         //添加omitempty    Genres   []string  `json:"genres,omitempty"`          //添加omitempty    Version  int32     `json:"version"`}

如果你想使用omitempty而不改变键名,那么你可以在struct标签中保留它为空-如:json:",omitempty"。注意,逗号是必要的。

现在,当你重新启动应用程序并刷新你的web浏览器时,你应该会看到如下响应:

Go结构体序列化的实现是怎样的

我们可以在这里看到,CreatedAt结构字段不再出现在JSON中,而且Year字段(值为0)也没有出现,这要感谢omitempty指令。其他字段使用了omitempty不受影响(例如Runtime和Genres)。

注意:您还可以通过简单地将结构体字段设置为不可导出来防止它出现在JSON序列化中。但使用json:“-“标记通常是一个更好的选择:明确告知阅读代码的人,你不希望该字段包含在json。

旧版本的go vet如果你试图在未导出的字段上使用struct标记会引发错误,但现在在go 1.16中已经修复了这个问题。

附加内容

结构体标签string指令

最后一个不太常用的struct标记指令是string。可以使用这个标签明确表示字段值序列化成JSON字符串类型。例如,如果我们希望Runtime字段的值表示为一个JSON字符串 (而不是数字)我们可以像这样使用string指令:

type Movie struct {    ID       int64     `json:"id"`    CreateAt time.Time `json:"-"`       //使用-指令    Title    string    `json:"title"`    Year     int32     `json:"year,omitempty"`       Runtime  Runtime   `json:"runtime,omitempty,string"`     Genres   []string  `json:"genres,omitempty"`           Version  int32     `json:"version"`}

JSON序列化结果如下所示:

{"id": 123,"title": "Casablanca","runtime": "102",   //这是字符串"genres": [    "drama",     "romance",     "war"    ],"version": 1 }

注意string指令只对int, uint, float*或bool类型的字段有效。对于任何其他类型的结构体字段没有作用。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网行业资讯频道,感谢您对编程网的支持。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Go结构体序列化的实现是怎样的

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Go结构体序列化的实现是怎样的

Go结构体序列化的实现是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。我们将回到之前写的showMovieHandler方法,并更新它以返回一个JSON响
2023-06-29

golang结构体序列化怎么实现

在Go中,可以使用encoding/json包来实现结构体的序列化和反序列化。首先,需要导入encoding/json包:import "encoding/json"然后,定义一个结构体类型,例如:type Person struc
2023-10-22

Golang怎么使用gob实现结构体的序列化

本文小编为大家详细介绍“Golang怎么使用gob实现结构体的序列化”,内容详细,步骤清晰,细节处理妥当,希望这篇“Golang怎么使用gob实现结构体的序列化”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Gol
2023-07-05

带指针的结构体序列化

哈喽!大家好,很高兴又见面了,我是编程网的一名作者,今天由我给大家带来一篇《带指针的结构体序列化》,本文主要会讲到等等知识点,希望大家一起学习进步,也欢迎大家关注、点赞、收藏、转发! 下面就一起来看看吧!问题内容具有如下结构层次结构:typ
带指针的结构体序列化
2024-04-04

Golang使用gob实现结构体的序列化过程详解

Golangstruct类型数据序列化用于网络传输数据或在磁盘上写入数据。在分布式系统中,一端生成数据、然后序列化、压缩和发送;在另一端,接收数据、然后解压缩、反序列化和处理数据,整个过程必须快速有效
2023-03-08

go语言string转结构体的实现

本文主要介绍了go语言string转结构体的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-03-19

Linux目录结构具体是怎样的

今天就跟大家聊聊有关Linux目录结构具体是怎样的,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Linux目录结构==================================
2023-06-04

C语言结构体是怎么样的

这篇文章给大家分享的是有关C语言结构体是怎么样的的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。结构体结构是一些值的集合,这些值称为成员变量。结构的每个成员是不同类型的变量。为什么要有结构体比如说,描述一个学生时,
2023-06-29

Linux的底层体系结构是怎样的

本文小编为大家详细介绍“Linux的底层体系结构是怎样的”,内容详细,步骤清晰,细节处理妥当,希望这篇“Linux的底层体系结构是怎样的”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。计算机的工作模式对于一个计算机
2023-06-16

Python数据结构列表是怎样的

Python数据结构列表是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。正则小练习:匹配出以下字符串所有url,import re def find_ur
2023-06-22

WCF序列化流程是怎样的

本篇内容介绍了“WCF序列化流程是怎样的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!为什么WCF序列化:我们这里先来介绍一下为什么需要序列
2023-06-17

Python列表的数据结构是怎么样的

这篇文章给大家分享的是有关Python列表的数据结构是怎么样的的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Python 列表的数据结构是怎么样的?列表实际上采用的就是数据结构中的顺序表,而且是一种采用分离式技术
2023-06-08

PHP数据结构:序列化与反序列化的艺术,实现数据持久化与传输

在 php 中,序列化将数据结构转换为字符串,而反序列化将字符串还原为数据结构,实现数据的持久化和传输。序列化函数 serialize 将数据结构转换为字符串,而 unserialize 函数从字符串中还原序列化后的数据。序列化可用于数据持
PHP数据结构:序列化与反序列化的艺术,实现数据持久化与传输
2024-05-14

Java的序列化与反序列化怎么实现

本篇内容介绍了“Java的序列化与反序列化怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java对象的序列化Java平台允许我们在内
2023-07-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录