前言大家好,周五我是程序员,继续上一期,看看结构体还有哪些操作。没时间上车的同学请戳:Go语言基础结构(春季篇)、Go语言基础结构(夏季篇)。如果以后匿名字段结构遇到anonymous这个词,就当作没有名字。匿名加上字段结构代码。packagemainimport"fmt"typeStudentstruct{stringint//string//error:duplicateFieldString//int//error:duplicateFieldString}funcmain(){vars1=Student{"666",0,}fmt.Println(s1)}line8andLine代码9,如果去掉注释,会报错。这说明了一个问题。如果是匿名字段结构,匿名字段类型不能重复,如上代码所示。结构嵌套结构嵌套,顾名思义,一个结构嵌套另一个结构。假设一个学生的信息,假设有三个字段:姓名,年龄,性别。这个学生必须属于一个班级。假设这个班级的信息包括年级、班级、班主任姓名。创建一个结构体根据上面的描述,我们知道肯定有两个结构体,至少一个是student,一个是class。类结构typeClassesstruct{Gradeint//年级Classint//classTeacherNamestring//班主任姓名}学生结构typeStudentstruct{Namestruct//nameAgeint//ageGenderstring//genderclassClasses//class}可以看第五行代码,字段结构体的类型直接是一个结构体,就是结构体嵌套。当一个结构不能完整描述一个对象时,或者当原来独立的对象之间存在关联时,就需要进行结构嵌套。嵌套结构赋值方法一、直接赋值嵌套结构funcmain(){vars1=Student{姓名:"张三",年龄:18,性别:"男",class:Classes{Grade:2020,Class:1,TeacherName:"张三的老师",},}fmt.Println(s1)}方法二,单独赋值funcmain(){varc1=Classes{Grade:2020,Class:1,TeacherName:"张三的老师",}vars2=Student{Name:"张三",年龄:18,性别:"男",class:c1,}fmt.Println(s2)}两次执行的结果其实和方法一和方法二在本质上是一样的,只是第二种方法分别分配嵌套结构。匿名嵌套字段我们上面的Student结构是这样写的。typeStudentstruct{Namestring//NameAgeint//AgeGenderstring//GenderclassClasses//Class}但实际上,第五行代码的字段可以省略,就像这样。typeStudentstruct{Namestring//NameAgeint//AgeGenderstring//GenderClasses//Class}但是在赋值的时候一定要注意,因为Student结构是没有字段名的,所以不能用上面的方法赋值。这种。funcmain(){vars1=Student{Name:"张三",年龄:18,性别:"男",班级:Classes{年级:2020,班级:1,TeacherName:"张三的老师",},}}就是这样对,第5行的字段名就是Classes结构体的名字。执行结果还是一样。补充上面的是在定义变量的时候直接赋值。其实不管是结构体还是嵌套结构体,还有另外一种方法,就是通过的方法来赋值。代码如下。结构嵌套默认结构嵌套,结构仍然有字段名。typeStudentstruct{Namestring//NameAgeint//AgeGenderstring//GenderclassClasses//Class}所以赋值代码如下。funcmain(){vars1Students1.Name="张三"s1.Age=18s1.Gender="男"s1.class.Grade=2020s1.class.Class=1s1.class.TeacherName="张三的老师"fmt.Println(s1)}从第六行代码开始,通过s1找到class字段,然后根据class找到class对应的具体值进行赋值。匿名嵌套字段匿名嵌套字段没有字段名称,只有字段类型。typeStudentstruct{Namestring//NameAgeint//AgeGenderstring//GenderClasses//Class}所以赋值和上面的不一样,是这样的。funcmain(){vars1Students1.Name="张三"s1.Age=18s1.Gender="男"s1.Classes.Grade=2020s1.Classes.Class=1s1.Classes.TeacherName="张三的老师"fmt.Println(s1)}直接通过s1找到Classes结构,然后根据这个结构在里面找到具体的值,并赋值。其实类似于定义变量时赋值。但毕竟执行结果还是一样,只是赋值形式不同而已。根据嵌套结构和匿名嵌套结构重新赋值时可以得出结论。如果嵌套结构有字段名,则使用字段名查找具体的字段并赋值。如果是嵌套结构的匿名字段,则使用嵌套结构的名称查找具体字段并赋值。嵌套结构字段冲突这种冲突问题其实比较少见。通常,这个问题只会出现在匿名嵌套的场景中。还是上面的结构,但是可以这样赋值。funcmain(){vars1Students1.Name="张三"s1.Age=18s1.Gender="男"s1.Classes.Grade=2020s1.Classes.Class=1s1.Classes.TeacherName="张三的老师"//#########拆分##########s1.Grade=2020//LeavingoutClassess1.Class=1//LeavingoutClassess1.TeacherName="张三的老师"//第10行ofClassesfmt.Println(s1)}省略,直接通过s1.Grade赋值,其实就是省了一个Classes,但是这个操作只能在匿名嵌套结构中使用。但是,如果我将结构更改为此。//classtypeClassesstruct{Gradeint//gradeClassint//classTeacherNamestring//班主任姓名}//coursetypeCoursestruct{CourseNamestring//课程名称TeacherNamestring//教师姓名}//studenttypeStudentstruct{Namestring//nameAgeint//ageGenderstring//性别Classes//ClassCourse//Teacher}Student结构有两个匿名嵌套结构,一个是Classes,一个是Course。但是有一个字段是冲突的,就是TeacherName。如果以惰性方式分配值会发生什么?funcmain(){vars1Students1.Name="张三"s1.Age=18s1.Gender="男"s1.Grade=2020s1.Class=1s1.TeacherName="张三的老师"fmt.Println(s1)}第8行,直接找到TeacherName字段,然后就出问题了。意思很简单,就是不知道是Classes的TeacherName还是Course的TeacherName。这个时候就必须要指定了。s1.Classes.TeacherName="张三的班主任"s1.Course.TeacherName="张三的老师"总结个人建议,尽量不要使用匿名嵌套结构。如果使用匿名嵌套结构,尽可能使用标准赋值而不是惰性赋值。如果使用lazy方法,一定要注意是否存在字段冲突。最后总结以上我们学习了Go基础结构体的匿名字段结构,结构体嵌套,匿名结构体嵌套,匿名嵌套结构体字段冲突。小伙伴们一定要实践一下,自己敲代码。坚持就是胜利,奥利!
