前言
结构体是将多个任意类型的命名变量组合在一起的聚合数据类型,通过结构体,可以多维度/方面的聚合逻辑数据,形成一个整体,其中的这些命名变量叫做结构体的成员。
Struct
声明:
1 | // 声明一个结构体类型 |
结构体成员(变量名称)推荐使用大写字母开头,目的是为了方便与json进行转换,具体说明可以看后面的部分。
简单使用
1 | // 声明结构体类型的实例,三种方式,前两种声明的都是指针,后面一种是直接生产对象本身,初始属性值都是零值: |
构造和比较
1 | /* |
结构体嵌套
1 | /* |
匿名结构体嵌套
1 | /* |
JSON
Json是非常常见的数据接收和发送的格式化标准,其逻辑结构与struct非常相似,go提供标准库encoding/json来支持对json数据的处理和转换操作。
下面举例说明struct和json之间的转换:
struct => json序列化
1 | type Movie struct { |
上面这个例子中,json序列化时会忽略小写开头的结构体成员,如果想要在json处理时显示成员为小写或别名,可以显示地为其添加标签:
1 | type Movie2 struct { |
这时输出的成员actor就是小写了,同理,标签这里也可以写为别名。注意:json:"actor"
,冒号中间不要有空格。
json => struct反序列化
1 | // 沿用上面例子的变量和结构体 |
这里没注意踩了一个坑,data2在序列化之前是[]Movie2
的slice结构,在声明了一个Movie2 struct类型的变量指针去接收json反序列化的数据时抛出了异常,这里应该同样使用[]Movie2
的slice类型变量.
这里使用的Unmarshal方法适用的对象为已经在单个或已内存中的json对象,而涉及文件(socket/http等)读取的byte流json数据,则适合使用另一种反序列化方式json.Decoder(),这种方式不会一次把字节流读取进内存中,而是会逐个读取,适用于这些场景。
使用举例
1 | package main |
运行结果:
1 | encoding/json: second decode after error impossible |
总结
Golang结构体有许多特性,且与json结合紧密,日后会经常用到,需要熟练掌握。