结构体简介
介绍:
Go语言中的基础数据类型可以表示一些事务的基本属性,但是我们想表达一个事务的全部或部分属性时(比如一个人,她的姓名、年龄、爱好等属性),就无法满足需求了,Go语言为我们提供了一种自定义数据类型,可以封装多个基本数据类型,叫结构体,也就是struct
结构体相当于python里给类传的参数,python写法:self.name = name,self.age=age.
结构体
一、结构体定义
使用type和struct来定义结构体
type 结构体名称 struct {
字段名 字段类型
字段名 字段类型
}
其中
1.结构体名称: 就是自定义结构体的名称
2.字段名: 表示结构体的字段名,结构体字段必须唯一
3.字段类型: 表示结构体的字段类型,例如 string int等
举个例子,我们定义一个名称为 Person的结构体
type Person struct {
name string
city string
age int
}
同样的字段类型 还可以写在一行里
type Person struct {
name , city string
age int
}
这样我们就拥有Person的自定义类型,它有name,city,age三个字段,分别表示姓名、城市、年龄,这样我们使用Person这个结构体就能很方便的在程序中存储人的信息了
二、结构体实例化
//定义结构体
type Person struct {
name , city string
age int
}
func main(){
var p1 Person //实例化结构体
p1.name = "张三" //通过p1访问结构体的字段并赋值,例如01.name = "张三"
p1.city = "北京"
p1.age = 18
fmt.Println(p1)
}
结果:
{张三 北京 18}
三、匿名结构体
在定义一些临时数据结构等场景下还可以使用匿名结构体
func main(){
//定义匿名结构体
var User struct {
Name string
Age int
}
//实例化匿名结构体
User.Name = "李四"
User.Age = 18
fmt.Println(User)
}
结果 :
{李四 18}
四、对结构体指针 进行实例化
可以取结构体的指针地址进行实例化,那么p1就是一个 带指针地址的变量
type Person struct {
name , city string
age int
}
func main(){
p1 := &Person{} //取Person的内存地址进行实例化
p1.name = "王五" //跟平常的实例化没有区别,很方便
p1.city = "上海"
p1.age = 19
fmt.Println(p1)
fmt.Printf("类型为: %T",p1) //打印p1的类型
}
----------------------------结果----------------------------
结果:
&{王五 上海 19}
类型为: *main.Person //代表p1是一个带指针地址的变量
五、使用值得列表进行实例化
实例化结构体得时候可以简写,也就是说实例化得时候可以不写Key,只写Value
type Person struct {
name , city string
age int
}
func main(){
p1 := &Person{
"张三",
"北京",
20,
}
fmt.Println(p1)
fmt.Printf("类型为: %T",p1)
}
结果:
--------------------------------结果------------------------
&{张三 北京 20}
类型为: *main.Person
这么实例化得时候 需要注意:
1.必须实例化结构体得所有字段
2.实例化得顺序必须跟结构体定义得顺序一样
3.该方式不能和平常得 Key/Value实例化 混用
六、先定义一个结构体, 然后在函数里 实例化 这个结构体,并返回指针类型的结构体(有的文章称之为 构造函数)
//定义一个结构体
type person struct {
name string
city string
age int8
}
//在函数里实例化这个结构体,*person代表返回值必须时指针类型,所以必须return &person取出结构体的指针地址进行返回
func newPerson(name, city string, age int8) *person {
return &person{ //实例化person这个结构体
name: name, //结构体的name字段等于函数传进来的name字段
city: city, //结构体的city字段等于函数传进来的city字段
age: age, //结构体的age字段等于函数传进来的age字段
}
}
func main() {
p1 := newPerson("张三", "北京", 18) //初始化函数,进行传参
fmt.Println(p1)
}
---------------------结果---------------------------
&{张三 北京 18}
七、嵌套结构体
一个结构体可以嵌套 另一个结构体或结构体指针
结果:
{张三 19 {河北 唐山}}
八、匿名嵌套结构体
type User struct {
Name string
Age int8
Address //匿名结构体
}
//地址结构体
type Address struct {
Province string
City string
}
func main() {
var user2 User
user2.Name = "李四"
user2.Age = 20
user2.Address.Province = "河北"
user2.Address.City = "唐山"
fmt.Println(user2)
}
结果:
{李四 20 {河北 唐山}}
九、结构体标签(tag)
Tag是结构体的元信息,可以在运行的时候通过反射的机制读取出来
例如我们为Student结构体的每个字段定义json序列化时使用的tag
type Student struct {
ID int `json:"id"` //通过指定tag实现json序列化该字段时的key,json序列化之后,ID字段就变成id了,就是这个作用
Gender string `json:"xingbie"`
name string
}
func main() {
s1 := Student{
ID: 1,
Gender: "男",
name: "张三",
}
data, err := json.Marshal(s1)
if err != nil {
fmt.Println("json marshal failed!")
return
}
fmt.Printf("json str:%s\n", data)
}
-------------------结果-----------------------------------
json str:{"id":1,"xingbie":"男"}
//id就是结构体里ID的tag,xingbie是结构体里Gender的tag,所以作用就是 结构体被序列化之后,key的别名