Go语言基础之结构体(秋日篇)如何改写成长尾词?

2026-04-01 21:411阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2836个文字,预计阅读时间需要12分钟。

Go语言基础之结构体(秋日篇)如何改写成长尾词?

匿名字段结构体+如以后再遇到+匿名+这个+词,就把它当作+没有名字+的意思。+匿名字段结构体+代码:+package+main+import+fmt+type+Student+struct+%7B+string+i%7D+package+main+import+fmt+type+Student+struct+%7B+string+i%7D

匿名字段结构体

如果以后再遇到匿名这个,就把他当作没有名字的意思。

匿名加字段结构体代码

package main import "fmt" type Student struct { string int //string //error:duplicate field string //int //error:duplicate field string } func main() { var s1 = Student{ "666", 0, } fmt.Println(s1) }

8行和第9行代码,如果去掉注释会报错。

这就说明了个问题,如果是匿名字段结构体,匿名字段类型是不能重复的,如上述代码所示。


结构体嵌套

结构体嵌套,就如名字一样,一个结构体,嵌套了另外一个结构体。

假设

一个学生的信息,假设有姓名年龄性别,这三个字段。

这个学生必定要归属一个班级的,假设这个班级的信息有年级几班班主任姓名


创建结构体

根据上述叙述,我们知道一定是有两个结构体的,至少一个是学生,一个是班级。

班级结构体

type Classes struct { Grade int //年级 Class int //班级 TeacherName string //班主任姓名 }

学生结构体

type Student struct { Name string //姓名 Age int //年龄 Gender string //性别 class Classes //所属班级 }

可以看到第5行代码,结构体字段类型直接是一个结构体,这就是结构体嵌套、

当一个结构体不能完整描述一个对象时,或者说本来就是独立的对象有关联时,就需要结构体嵌套。


嵌套结构体赋值方式一,直接赋值嵌套结构体

func main() { var s1 = Student{ Name: "张三", Age: 18, Gender: "男", class: Classes{ Grade: 2020, Class: 1, TeacherName: "张三的老师", }, } fmt.Println(s1) }

方式二,分开赋值

func main() { var c1 = Classes{ Grade: 2020, Class: 1, TeacherName: "张三的老师", } var s2 = Student{ Name: "张三", Age: 18, Gender: "男", class: c1, } fmt.Println(s2) }

两次执行结果

其实方式一方式二的本质是一样的,只不过是方式二嵌套的结构体单独赋值了而已。


匿名嵌套字段

上述我们的Student结构体是这样写的。

type Student struct { Name string //姓名 Age int //年龄 Gender string //性别 class Classes //所属班级 }

但是其实第5行代码的字段是可以省略的,就像这样。

type Student struct { Name string //姓名 Age int //年龄 Gender string //性别 Classes //所属班级 }

但是在赋值时,就要注意了,因为Student结构体已经没有字段名了,所以就不能使用上述的方式赋值了

需要这种。

func main() { var s1 = Student{ Name: "张三", Age: 18, Gender: "男", Classes: Classes{ Grade: 2020, Class: 1, TeacherName: "张三的老师", }, } }

没错,第5行的字段名是Classes结构体名。

执行结果还是一样的。


补充

上述是直接通过定义变量时就直接赋值了。

其实不管是结构体,还是嵌套结构体,都还有一种方法,就是通过.的方式赋值,代码如下。

结构体嵌套

默认的结构体嵌套,结构体还是有字段名的。

type Student struct { Name string //姓名 Age int //年龄 Gender string //性别 class Classes //所属班级 }

所以赋值代码如下。

func main() { var s1 Student s1.Name = "张三" s1.Age = 18 s1.Gender = "男" s1.class.Grade = 2020 s1.class.Class = 1 s1.class.TeacherName = "张三的老师" fmt.Println(s1) }

第6行代码开始,通过s1找到class这个字段,再根据class找到class具体对应的值进行赋值。


匿名嵌套字段

匿名嵌套字段是没有字段名的,是有一个字段类型

type Student struct { Name string //姓名 Age int //年龄 Gender string //性别 Classes //所属班级 }

所以赋值跟上述也不太一样,是这样的。

func main() { var s1 Student s1.Name = "张三" s1.Age = 18 s1.Gender = "男" s1.Classes.Grade = 2020 s1.Classes.Class = 1 s1.Classes.TeacherName = "张三的老师" fmt.Println(s1) }

通过s1直接找到Classes这个结构体,再根据这个结构体找到里面具体的值,进行赋值。

其实跟定义变量时赋值相似。

但是终究执行结果,还是一样的,只是赋值形式不同。


Go语言基础之结构体(秋日篇)如何改写成长尾词?

结论

根据嵌套结构体匿名嵌套结构体再赋值时可以发现。

如果嵌套结构体有字段名,通过字段名找具体的字段,进行赋值。

如果是嵌套结构体匿名字段,通过嵌套结构体的名字,找具体字段,进行赋值。


嵌套结构体字段冲突

这个冲突的问题,其实还是比较少见的,这个问题通常情况下,只会出现在匿名嵌套场景中。

还是上述的结构体,但是赋值可以是这样操作的。

func main() { var s1 Student s1.Name = "张三" s1.Age = 18 s1.Gender = "男" s1.Classes.Grade = 2020 s1.Classes.Class = 1 s1.Classes.TeacherName = "张三的老师" //######### 分割 ########## s1.Grade = 2020 //省去了Classes s1.Class = 1 //省去了Classes s1.TeacherName = "张三的老师" //省去了Classes fmt.Println(s1) }

第10行,直接通过s1.Grade赋值,其实是省去了一个Classes,但是这种操作,只有在匿名嵌套结构体中可以使用。

但是如果我将结构体改成这样子。

//班级 type Classes struct { Grade int //年级 Class int //班级 TeacherName string //班主任姓名 } //课程 type Course struct { CourseName string //课程名字 TeacherName string //任课老师姓名 } //学生 type Student struct { Name string //姓名 Age int //年龄 Gender string //性别 Classes //所属班级 Course //任课老师 }

Student结构体有两个匿名嵌套结构体,一个是Classes,一个是Course

但是有一个字段,是冲突的,就是TeacherName,如果还是通过懒的方式赋值,会发生什么呢?

func main() { var s1 Student s1.Name = "张三" s1.Age = 18 s1.Gender = "男" s1.Grade = 2020 s1.Class = 1 s1.TeacherName = "张三的老师" fmt.Println(s1) }

第8行,直接找TeacherName字段,这时候就会出问题了。

意思很简单,就是不知道是ClassesTeacherName还是CourseTeacherName

这时候,就必须要指定了。

s1.Classes.TeacherName = "张三的班主任" s1.Course.TeacherName = "张三的任课老师"

总结

个人建议,还是尽量不要使用匿名嵌套结构体

如果使用了匿名嵌套结构体,尽可能的采用标准方式赋值,不要采用懒得方式。

如果采用了懒的方式,一定要注意有没有字段冲突

本文共计2836个文字,预计阅读时间需要12分钟。

Go语言基础之结构体(秋日篇)如何改写成长尾词?

匿名字段结构体+如以后再遇到+匿名+这个+词,就把它当作+没有名字+的意思。+匿名字段结构体+代码:+package+main+import+fmt+type+Student+struct+%7B+string+i%7D+package+main+import+fmt+type+Student+struct+%7B+string+i%7D

匿名字段结构体

如果以后再遇到匿名这个,就把他当作没有名字的意思。

匿名加字段结构体代码

package main import "fmt" type Student struct { string int //string //error:duplicate field string //int //error:duplicate field string } func main() { var s1 = Student{ "666", 0, } fmt.Println(s1) }

8行和第9行代码,如果去掉注释会报错。

这就说明了个问题,如果是匿名字段结构体,匿名字段类型是不能重复的,如上述代码所示。


结构体嵌套

结构体嵌套,就如名字一样,一个结构体,嵌套了另外一个结构体。

假设

一个学生的信息,假设有姓名年龄性别,这三个字段。

这个学生必定要归属一个班级的,假设这个班级的信息有年级几班班主任姓名


创建结构体

根据上述叙述,我们知道一定是有两个结构体的,至少一个是学生,一个是班级。

班级结构体

type Classes struct { Grade int //年级 Class int //班级 TeacherName string //班主任姓名 }

学生结构体

type Student struct { Name string //姓名 Age int //年龄 Gender string //性别 class Classes //所属班级 }

可以看到第5行代码,结构体字段类型直接是一个结构体,这就是结构体嵌套、

当一个结构体不能完整描述一个对象时,或者说本来就是独立的对象有关联时,就需要结构体嵌套。


嵌套结构体赋值方式一,直接赋值嵌套结构体

func main() { var s1 = Student{ Name: "张三", Age: 18, Gender: "男", class: Classes{ Grade: 2020, Class: 1, TeacherName: "张三的老师", }, } fmt.Println(s1) }

方式二,分开赋值

func main() { var c1 = Classes{ Grade: 2020, Class: 1, TeacherName: "张三的老师", } var s2 = Student{ Name: "张三", Age: 18, Gender: "男", class: c1, } fmt.Println(s2) }

两次执行结果

其实方式一方式二的本质是一样的,只不过是方式二嵌套的结构体单独赋值了而已。


匿名嵌套字段

上述我们的Student结构体是这样写的。

type Student struct { Name string //姓名 Age int //年龄 Gender string //性别 class Classes //所属班级 }

但是其实第5行代码的字段是可以省略的,就像这样。

type Student struct { Name string //姓名 Age int //年龄 Gender string //性别 Classes //所属班级 }

但是在赋值时,就要注意了,因为Student结构体已经没有字段名了,所以就不能使用上述的方式赋值了

需要这种。

func main() { var s1 = Student{ Name: "张三", Age: 18, Gender: "男", Classes: Classes{ Grade: 2020, Class: 1, TeacherName: "张三的老师", }, } }

没错,第5行的字段名是Classes结构体名。

执行结果还是一样的。


补充

上述是直接通过定义变量时就直接赋值了。

其实不管是结构体,还是嵌套结构体,都还有一种方法,就是通过.的方式赋值,代码如下。

结构体嵌套

默认的结构体嵌套,结构体还是有字段名的。

type Student struct { Name string //姓名 Age int //年龄 Gender string //性别 class Classes //所属班级 }

所以赋值代码如下。

func main() { var s1 Student s1.Name = "张三" s1.Age = 18 s1.Gender = "男" s1.class.Grade = 2020 s1.class.Class = 1 s1.class.TeacherName = "张三的老师" fmt.Println(s1) }

第6行代码开始,通过s1找到class这个字段,再根据class找到class具体对应的值进行赋值。


匿名嵌套字段

匿名嵌套字段是没有字段名的,是有一个字段类型

type Student struct { Name string //姓名 Age int //年龄 Gender string //性别 Classes //所属班级 }

所以赋值跟上述也不太一样,是这样的。

func main() { var s1 Student s1.Name = "张三" s1.Age = 18 s1.Gender = "男" s1.Classes.Grade = 2020 s1.Classes.Class = 1 s1.Classes.TeacherName = "张三的老师" fmt.Println(s1) }

通过s1直接找到Classes这个结构体,再根据这个结构体找到里面具体的值,进行赋值。

其实跟定义变量时赋值相似。

但是终究执行结果,还是一样的,只是赋值形式不同。


Go语言基础之结构体(秋日篇)如何改写成长尾词?

结论

根据嵌套结构体匿名嵌套结构体再赋值时可以发现。

如果嵌套结构体有字段名,通过字段名找具体的字段,进行赋值。

如果是嵌套结构体匿名字段,通过嵌套结构体的名字,找具体字段,进行赋值。


嵌套结构体字段冲突

这个冲突的问题,其实还是比较少见的,这个问题通常情况下,只会出现在匿名嵌套场景中。

还是上述的结构体,但是赋值可以是这样操作的。

func main() { var s1 Student s1.Name = "张三" s1.Age = 18 s1.Gender = "男" s1.Classes.Grade = 2020 s1.Classes.Class = 1 s1.Classes.TeacherName = "张三的老师" //######### 分割 ########## s1.Grade = 2020 //省去了Classes s1.Class = 1 //省去了Classes s1.TeacherName = "张三的老师" //省去了Classes fmt.Println(s1) }

第10行,直接通过s1.Grade赋值,其实是省去了一个Classes,但是这种操作,只有在匿名嵌套结构体中可以使用。

但是如果我将结构体改成这样子。

//班级 type Classes struct { Grade int //年级 Class int //班级 TeacherName string //班主任姓名 } //课程 type Course struct { CourseName string //课程名字 TeacherName string //任课老师姓名 } //学生 type Student struct { Name string //姓名 Age int //年龄 Gender string //性别 Classes //所属班级 Course //任课老师 }

Student结构体有两个匿名嵌套结构体,一个是Classes,一个是Course

但是有一个字段,是冲突的,就是TeacherName,如果还是通过懒的方式赋值,会发生什么呢?

func main() { var s1 Student s1.Name = "张三" s1.Age = 18 s1.Gender = "男" s1.Grade = 2020 s1.Class = 1 s1.TeacherName = "张三的老师" fmt.Println(s1) }

第8行,直接找TeacherName字段,这时候就会出问题了。

意思很简单,就是不知道是ClassesTeacherName还是CourseTeacherName

这时候,就必须要指定了。

s1.Classes.TeacherName = "张三的班主任" s1.Course.TeacherName = "张三的任课老师"

总结

个人建议,还是尽量不要使用匿名嵌套结构体

如果使用了匿名嵌套结构体,尽可能的采用标准方式赋值,不要采用懒得方式。

如果采用了懒的方式,一定要注意有没有字段冲突