主要是敲代码,敲的过程中会慢慢体会。
结构体是用户定义的类型,表示若干字段的集合,目的是将数据整合在一起。
简单的说,类似Java中的实体类。存储某个实体属性的集合。
注意:结构体名字,结构体属性名的首字母大写代表其余的包可以访问该结构体,类似Java中的public公有属性。
如果,结构体的名字首字母或者属性首字母是小写,其余的包不能访问该结构体,类似于Java中的private私有属性。
type 结构体名字 struct{
属性名 数据类型
属性名 数据类型
......
}
结构体的声明,相同类型的可以放到一行。
type Employee struct {
firstName string
lastName string
age int
}
type Employee struct {
firstName,lastName string
age int
}
结构体初始化有多种方式。直接看代码吧,有注释。
// Employee 结构体
type Employee struct {
firstname, lastname string
age int
}
// 测试结构体
func testStruct() {
// 方式一:把属性写出来,键值对
emp1 := Employee{
firstname: "Sam",
lastname: "Jam",
age: 18,
}
fmt.Println("Employee 1 is ", emp1)
// 方式二:不写属性名,但是要和结构体中的属性顺序一一对应,以及属性的数量是不能缺少的
emp2 := Employee{
"Sam",
"Com",
20,
}
fmt.Println("Employee 2 is ", emp2)
// 方式三:匿名结构体,并且赋值
emp3 := struct {
name string
age int
}{
name: "Rose",
age: 20,
}
fmt.Println("Employee 3 is ", emp3)
// 空结构体
var emp4 Employee
fmt.Println("Employee 4 is ", emp4)
// 获取结构体的某个属性直接是结构体初始化对象.属性名
emp5 := Employee{
firstname: "z",
lastname: "ee",
}
fmt.Println("Employee 5 is ", emp5)
fmt.Println("获取实例的属性:", emp5.lastname)
var emp6 Employee
emp6.age = 22
emp6.firstname = "xiao"
fmt.Println("Employee 6 is ", emp6)
// 结构体指针,也就是指向结构体的指针
emp8 := &Employee{
firstname: "name",
lastname: "xing",
age: 22,
}
// 下面这两种方式都行,go内直接隐式解引用,直接调用。
// 显式解引用
fmt.Println("FirstName:", (*emp8).firstname)
// 隐式解引用
fmt.Println("lastName", emp8.age)
}
结构体的嵌套就是在一个结构体中属性的数据类型,是另一个结构体。另一个结构体中的属性可以直接被访问到。
举例:
type Address struct {
city, state string
}
type Student struct {
name string
age int
// 以另一个结构体作为数据类型
address Address
}
func TestUpStruct() {
var police Police
police.name = "China"
police.Address = Address{
city: "中国",
state: "四川",
}
// 提升字段,匿名结构体在另一个结构体中,叫提升字段,外部结构体可以直接访问内部结构体中的属性,和外部结构体中的属性一样的
fmt.Println("Name:", police.name)
fmt.Println("city:", police.city)
fmt.Println("state:", police.state)
}
首先它是一个指针,是指向结构体的指针。初始化的时候,可以取结构体的地址。看代码。
func testStudent() {
// 取结构体的地址进行初始化
stuInfo1 := &Student{
name: "zhangsan",
age: 18,
address: Address{
city: "nanjing",
state: "江宁区",
},
}
// 小细节问题:当初始化结构体为指针类型,输出结构体会带&符号
// 如果使用初始化的变量获取属性,就没有&符号
fmt.Println("stuInfo 1 is ", stuInfo1)
fmt.Println("stuAge 1 is ", stuInfo1.age)
var stuInfo2 Student
stuInfo2.name = "lisi"
stuInfo2.age = 22
stuInfo2.address = Address{
city: "深圳",
state: "南山区",
}
fmt.Println("stuInfo 2 is ", stuInfo2)
}
指的是可以导入其他包中的结构体,但是结构体的名字首字母需要大写,结构体中的属性名也需要大写。
package structs
// Spec 电脑配置规格,结构体名首字母大写开头,说明其它的包可以的访问到,结构体中的属性也是一样的。
type Spec struct { // exported field
Maker string // exported field
Model string // unexported field
Price int // exported field
}
// 导出结构体和字段,结构体以大写字母开头的,go中其他的包也可以直接访问
func testOutStruct() {
var spec structs.Spec
spec.Maker = "联想"
spec.Price = 10893
spec.Model = "2222"
fmt.Println("Spec:", spec)
}
如果两个结构体对象中的属性以及属性的值是相等的,那么这两个结构体是相等的。
// 测试结构体是否相等,两个结构体对应的属性相等,那么这个结构体是相同的
func testCat() {
cat1 := cat{
name: "huahua",
age: 2,
}
cat2 := cat{
name: "huahua",
age: 2,
}
if cat1 == cat2 {
fmt.Println("cat1 == cat2")
} else {
fmt.Println("cat != cat2")
}
}
注意:相等的比较不能是map,map是不能判断相等。看例子:
func testkeyVal() {
k1 := keyVal{
m: map[int]int{
1: 2,
},
}
k2 := keyVal{
m: map[int]int{
1: 2,
},
}
fmt.Println("k1 :", k1, " k2 :", k2)
/*if k1 == k2 {
fmt.Println("k1 == k2")
} else {
fmt.Println("map 类型的结构体属性是不能够比较的")
}*/
}
结构体需要掌握以下点:
1.结构体的定义
2.结构体的名字首字母大小写,属性名大小写
3.结构体的初始化,各种初始化方式
4.结构体指针
5.结构体嵌套
6.结构体的导入