结构体简介
介绍:
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 ", data) } -------------------结果----------------------------------- json str:{"id":1,"xingbie":"男"}
//id就是结构体里ID的tag,xingbie是结构体里Gender的tag,所以作用就是 结构体被序列化之后,key的别名