Go语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
struct特点
1、用来自定义复杂数据结构
2、struct里面可以包含一个或多个字段(属性)
3、struct类型可以定义方法,注意和函数的区分
4、struct类型是值类型
5、struct类型可以嵌套
6、结构体是用户单独定义的类型,不能和其他类型进行强制转换
7、Go中的struct没有构造函数,一般可以使用工厂模式来解决这个问题
8、我们可以为struct中的每个字段,写上一个tag。这个tag可以通过反射的机制获取到,最常用的场景就是json序列化和反序列化
9、访问结构体成员,用"."来连接,格式为:"结构体.成员名"
struct定义
可用type在全局或函数内定义新类型。
第一种,定义一个新的数据类型,结构体中只有一个成员。
typebigintint64typesmallintint8
新类型不是原类型的别名,除拥有相同数据存储结构外,它们之间没有任何关系,不会持有原类型任何信息。除非目标类型是未命名类型,否则必须显式转换。
第二种,定义一个新的数据类型,结构体中有多个成员。
typeoldboystruct{LinuxstringPythonstringGolangstring}
第三种,定义一个新的数据类型,指向结构体的指针。
typeLinuxstringtypeoldboystruct{*Linux}
不能同时嵌入某一类型和其指针类型,因为它们名字相同。实例如下:
packagemaintypeLinuxstringtypeoldboystruct{*LinuxLinux}funcmain(){}
编译错误:
./main.go:7:2:duplicatefieldLinux
struct初始化
有序初始化:结构体中的多个成员的值,必须一一对应。
无序初始化:结构体中的多个成员的值,无须一一对应,可初始化部分值。
packagemaintypeoldboystruct{LinuxstringPythonstringGolangstring}//有序初始化varordered=oldboy{"linux","python","golang"}//无序初始化vardisordered=oldboy{Golang:"golang"}funcmain(){}
结构体初始化方法有如下几种:
packagemainimport("fmt")typeoldboystruct{intstring}varoneoldboyfuncmain(){two:=new(oldboy)//同vartwo*oldboy=new(oldboy)three:=oldboy{1,"three"}four:=oldboy{}five:=oldboy{}six:=oldboy{2,"six"}//同varsix*oldboy=oldboy{2,"six"}fmt.Println(one,two,three,four,five,six)}
onethreefour返回oldboy类型变量;twofivesix返回*oldboy类型变量;若无初始化值,则默认为零值。
匿名字段
定义一个struct,定义的时候是字段名与其类型一一对应,实际上Go语言支持只提供类型,而不写字段名的方式,也就是匿名字段,或称为嵌入字段。
当匿名字段是一个struct的时候,那么这个struct所拥有的全部字段都被隐式地引入了当前定义的这个struct。
packagemainimport("fmt")typePersonstruct{namestringageintaddrstring}typeEmployeestruct{Person//匿名字段salaryintint//用内置类型作为匿名字段addrstring//类似于重载}funcmain(){em1:=Employee{Person{"oldboy",18,"北京"},10,,"首都",}fmt.Println(em1)varem2Person=em1.Personfmt.Println(em2)}
struct与tag应用
声明struct结构的时候,在属性的右侧用小米点括起来的内容叫标签(Tag),在转换成其它数据格式的时候,会使用其中特定的字段作为键值。例如转成json格式,实例如下:
packagemainimport("encoding/json""fmt")typeUserstruct{UserIdintUserNamestring}typeUserTagstruct{UserIdint`json:"user_id"bson:"user_id"`UserNamestring`json:"user_name"bson:"user_name"`}funcmain(){user:=User{UserId:1,UserName:"oldboy"}json_user,_:=json.Marshal(user)fmt.Printf("structUserecho:%v\n",string(json_user))user_tag:=UserTag{UserId:1,UserName:"oldboy"}json_user_tag,_:=json.Marshal(user_tag)fmt.Printf("structUserTagecho:%v\n",string(json_user_tag))}
运行结果:
structUserecho:{"UserId":1,"UserName":"oldboy"}structUserTagecho:{"user_id":1,"user_name":"oldboy"}
标签是struct类型的组成部分:
packagemainvaruser1struct{UserIdint`json:"user_id"`}varuser2struct{UserIdint`bson:"user_id"`}funcmain(){user1=user2}
编译错误:
./main.go:11:8:cannotuseuser2(typestruct{UserIdint"bson:\"user_id\""})astypestruct{UserIdint"json:\"user_id\""}inassignment