结构体
- 和C语言几乎一模一样
- 格式:
type 结构体类型名称 struct{
属性名称 属性类型;
属性名称 属性类型;
}
结构体变量的定义
格式:var 结构体名称 结构体类型
和切片和字典不一样,Go语言中结构体定义了就可以直接使用
结构体的初始化
- 定义的同时完全初始化
- 注意:定义的同时只能完全初始化
type Person struct{
name string
age int
}
var per Person = Person{"xxz",20}
per2 := Person{"xxz",20}
- 先定义后完全初始化
type Person struct{
name string
age int
}
var per Person
per = Person{"xxz",20}
per = Person{name:"xxz",age:20}
- 先定义后部分初始化
- 注意点:定义的同时部分初始化必须加上初始化的key
type Person struct{
name string
age int
}
var per Person
per = {name:"xxz"}
结构体和函数
- 结构体类型和数组一样,是值传递,函数内改变形参结构体属性的值不会影响到实参
type Person struct{
name string
age int
}
pp := Person{name:"xxz",age:18}
fmt.Println(pp.name)//"xxz"
change(pp)
fmt.Println(pp.name)//"xxz"
func change(pp Person){
pp.name = "zs"
}
复杂的结构体
- 结构体内的数据类型,如果是切片,字典这种数据类型,那么必须给他们初始化才能使用
type Person struct{
name string
age int
sce []int
dict map[string]string
}
var per Person
per.name = "xxz"// 不报错
per.age = 18//不报错
//per.sce[0] = 1//报错
//per.dict["name"] = "xxz"//报错
per.sce = make([]int,2)
per.sce[0] = 1
per.sce[1] = 2 //不报错
per.dict = make(map[string]string)
per.dict["name"] = "zs"
fmt.Println(per)//不报错
结构体类型的转换
- 只有当结构体完全相同,完全相同,完全相同时才能相互转换
- 包括属性名称,属性类型,属性顺序,属性个数完全相同
结构体匿名属性
- 没有名称的属性叫匿名属性
- 调用匿名属性用结构体名称.数据类型即可
type Person struct{
int
name string
}
var per Person = Person{666,"xxz"}
fmt.Println(per.int)//666
- 结构体匿名属性一般用于结构体的嵌套定义
type Date struct{
year int
month int
day int
}
type Person struct{
name string
// year int
// month int
// day int
Date
}
type Animal struct{
name string
// year int
// month int
// day int
// birthday Date
Date
}
/ /定义
var per Person = {"xxz",Date{1998,4,9}}
fmt.Println(per.name)//"xxz"
fmt.Println(per.Date.year)// 1998
结构体嵌套定义
- 第一种方式
type 结构体名称1 struct{
}
type 结构体名称2 struct{
结构体名称1
}
- 第二种方式
type 结构体名称1 struct{
}
type 结构体名称2 struct{
结构体名称1
}
type 结构体名称3 struct{
结构体名称2
}
- 第三种方式
type 结构体名称1 struct{
}
type 结构体名称2 struct{
}
type 结构体名称3 struct{
结构体名称1
结构体名称2
}
- 注意点:
1 结构体的属性类型不能是当前结构体的类型
2 只有匿名属性才会向上查找, 非匿名属性不会向上查找(访问结构体属性时,首先在源结构体内寻找属性,如果没有,再去嵌套的结构体内寻找属性)