开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:结构体使用细节(3)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9675
结构体使用细节(3)
内容介绍:
一、结构体的注意事项和使用细节4
二、序列化的使用场景
三、序列化的步骤
一、结构体的注意事项和使用细节4
内容:
struct的每个字段上可以写上一个tag,该tag可以通过反射机制获取。常见的使用场景就是序列化和反序列化。例如左侧为go服务器,右侧为浏览器,当浏览器发信息给go服务器后,go会去操作一个数据库,然后返回一个数据给浏览器。而当go返回一个结构体变量给客户端的时候,不可能把结构体本身作为数据返回,往往要把这个结构体做成一个字符串进行返回,要将结构体转换成字符串,就需要把结构体序列化。序列化就是把一个变量序列化成一个字符串,然后再返回给客户端。字符串现有一种通用的格式(json)。json不希望返回的字段是一个大写的字母(N),因为很多客户端喜欢返回的字段里是小写的字母(n)。可以给结构体加上tag,然后就可以指定一个小写的字段name。当写成小写的name后,对方会非常习惯,既可以在其他包访问字段,同时还可以更改字段名。json处理完后,字段名首字母是大写的,如果将json后的字段返回给其他程序(像jquery.php等)使用,其程序员可能会不习惯这种命名方式,且不可以使用小写monster,因为小写时无法使用其他包,处理后发现返回空串,此时需要使用tag标签来解决。因为struck结构体每个字段都可以用标签处理,struct的每个字段都添加一个tag,可以通过反射机制获取,常见的应用场景是序列化和反序列化,最主要的是序列化。
二、序列化的使用场景
左侧是一个客户端,右边是一个服务器端,客户端发出一个请求,Go语言回送了一个信息,假设服务器要返回一组monster变量值给客户端,进行查阅monster的信息,或者将来进行学生信息的查询。此时不可能把monster的值直接返回,通常情况下要把monster进行序列化,然后再把序列化的字符串返回给客户端,即结构体经json处理后再返回给客户端,客户端接收到monster的字符串后就可以进行处理。
内存分析图示意图
三、序列化的步骤
1. 创建一个Monster变量
假设有一个type和monster结构体,master里面有名字Name、年龄Age、技能Skill三个字段。首先创建一个monster变量,设定名字为牛魔王,年龄定为500岁,技能为芭蕉扇。
2. 将monster变量序列化为json格式
在golang官方文档中找到json包并引入,在Encoding json中有一个方法,叫做Marshal,Marshal函数会返回传入变量的json编码。引入json包后,使用json包中的marshal方法,返回得到byte切片,需要修改成fmt.Println("jsonstr", string(jsonstr),将切片转换成字符串,输出验证发现字段的首字母是大写的N、A、S,但是很多程序员并不习惯字段的首字母是大写的。因此我们有两种方案,第一种是把字段修改为小写形式,运行发现结果为一个空串,这是因为在json包中调用了Marshal方法,相当于是在别的包里使用了monster变量,但master字段是小写的,根据作用域的原则,在json里是无法访问内容配置的,只能使用大写字母,因此第一种方法不能解决问题。第二种则是要引入tag,只需要修改为Name string ‘json: "name"’,Age int ‘"json: "age"’,skill string‘"json: "ski11"’即可完成引入。执行后发现效果与想象完全一致。引入tag(‘json:“name”’)后,既能够序列化,又可以将反序列化的字符串通过网络返回给客户端,且客户端的程序员更加习惯首字母小写的形式,保持一种良好的兼容性。
核心代码:
l
type Monster struct{
Name string ‘json: "name"’
Age int ‘"json: "age"’
skill string‘"json: "ski11"’}
l
monster := Monster{”牛魔王”,500,“芭蕉扇~”}
jsonStr, err := json.Marsha1 (monster)
if err != nil {
fmt.Print1n("json处理错误",err)
}
fmt.Println("jsonstr",string(jsonstr))