结构struct
1. Go 中的struct与C中的struct非常相似,并且Go没有class
2. 使用 type <Name> struct{} 定义结构,名称遵循可见性规则(即首字母大写对外可见)。 type person struct{}
3. 支持指向自身的指针类型成员,支持匿名结构,可用作成员或定义成员变量
4. 匿名结构也可以用于struct的值,可以使用字面值对结构进行初始化
5. 允许直接通过指针来读写结构成员
6. 相同类型的成员可进行直接拷贝赋值
7. 支持 == 与 != 比较运算符,但不支持 > 或 <
8. 支持匿名字段,本质上是定义了以某个类型名为名称的字段
9. 嵌入结构作为匿名字段看起来像继承,但不是继承
10. 可以使用匿名字段指针
一、结构体的基本使用案例
package main import "fmt" /** 定义一个结构体,类似于其他语言的class */ type person struct { Name string Age int } func main() { // struct 对属性操作使用符号 . ;这里赋值采用两种方式,既可以使用默认值,也可以在外部赋值 a := person{ Name : "liang", Age : 29, } //a.Age = 29 fmt.Println("a修改前:", a) //第一次修改并打印 modifyPerson(a) fmt.Println("a第一次修改后:", a) //第二次修改并打印 modifyPersonPointer(&a) fmt.Println("a第二次修改后:", a) /** 假如有一种场景有很多需要修改person内容,那么每次传入都需要取地址符号,这样很麻烦,可以在赋值对时候直接取得对应对地址 这种方式是开发对推荐方式 */ b := &person{ Name : "xuli", Age : 27, } fmt.Println("b修改前:", b) modifyPersonPointer(b) fmt.Println("b修改后:", b) } /** 从打印结果可以看出这里传入对是值类型,修改person内容并不会修改person原始值 */ func modifyPerson(per person) { per.Age = 18 fmt.Println("修改时:", per) } func modifyPersonPointer(per *person) { per.Age = 19 fmt.Println("修改时:", per) }
运行结果:
a修改前: {liang 29} 修改时: {liang 18} a第一次修改后: {liang 29} 修改时: &{liang 19} a第二次修改后: {liang 19} b修改前: &{xuli 27} 修改时: &{xuli 19} b修改后: &{xuli 19}
二、匿名结构体以及结构体内嵌案例
package main import ( "fmt" ) /** 结构体嵌套,使用对就是匿名结构体 */ type person struct { UserName string UserAge int Constact struct{ Phone, City string } } func main() { /** 匿名结构体对应用案例 */ st := &struct { Name string Age int }{ Name : "liang", Age : 29, } fmt.Println(st) /** 机构体嵌套打印 */ per := person{UserName: "liangyongxing", UserAge: 29} per.Constact.Phone = "15701183662" per.Constact.City = "北京" fmt.Println(per) }
运行结果:
&{liang 29} {liangyongxing 29 {15701183662 北京}}
三、结构体的内嵌组合模拟继承案例
package main import ( "fmt" ) /** 这里说对是结构体对组合,它对功能类似于其他语言对继承 */ type Human struct { sex int } type teacher struct { Human Name string Age int } type Student struct { Human Name string Age int } func main() { /** 在初始化对时候Go将嵌入对结构名称当成属性一样对待,将对应Human作为属性,这样可以在初始化对时候直接赋值 第二种赋值方式可以通过符号 . 来操作赋值 */ tea := teacher{Name: "teacher", Age: 36, Human: Human{sex: 1}} // tea.Human.sex = 1 或者 tea.sex = 1 stu := Student{Name: "student", Age: 15, Human: Human{sex: 2}} //stu.Human.sex = 2 或者 tea.sex = 2 /** 1. 既然结构嵌入进来来,就和其他语言继承一样,可以直接使用父类对属性,即 tea.sex = 1 也是可以对 2. 那 1 方式简单为什么还要保留 tea.Human.sex = 1 这种方式呢?是因为为来防止外部引用有同名对属性,为了区分 */ fmt.Println(tea) fmt.Println(stu) }
运行结果:
{{1} teacher 36} {{2} student 15}