golang-嵌套结构体 [复制链接]
发表于 2025-10-12 13:35:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
结构体嵌套

golang中没有类,他通过结构体来实现其他编程语言中类的相干功能
具名结构体

根本语法

根本语法
golang的结构体嵌套特殊简单。
  1. type 结构体类型1 struct{
  2.     字段 类型1
  3.     字段 类型2
  4. }
  5. //这样就实现了结构体的嵌套
  6. type 结构体类型2 struct{
  7.     字段 类型1
  8.     字段 类型2
  9.     字段 结构体类型1
  10. }
复制代码
举例
  1. package struct_knowledge
  2. import "fmt"
  3. type Worker struct{
  4.         salary int
  5.         profession string
  6. }
  7. //具名嵌套结构体
  8. type Human struct{
  9.         Name string
  10.         Age int
  11.         Work Worker
  12. }
  13. func (w Worker) GetSalary(){
  14.         fmt.Printf("工资为%d\n",w.salary)
  15. }
  16. //访问具名结构体
  17. func VisitNestingStruct(){
  18.         var human Human
  19.        
  20.     //访问字段
  21.     /*
  22.             报错:human.salary undefined(type Human has no filed or method GetSalary)
  23.     */
  24.     //human.salary = 25
  25.    
  26.         //通过字段连锁访问
  27.         human.Work.salary = 20
  28.         fmt.Printf("结构体的实例为%v\n",human)
  29.         //通过字面量访问
  30.         human = Human{
  31.                 Age: 20,
  32.                 Name: "张三",
  33.                 Work: Worker{
  34.                         salary: 1000,
  35.                         profession: "no work",
  36.                 },
  37.         }
  38.         fmt.Printf("结构体的实例为%v\n",human)
  39.         //通过位置赋值
  40.         human = Human{
  41.                 "lisa",
  42.                 45,
  43.                 Worker{
  44.                         salary: 10000,
  45.                         profession: "waiter",
  46.                 },
  47.         }
  48.         fmt.Printf("结构体的实例为%v\n",human)
  49.         // 调用方法
  50.         /*
  51.                 报错:human.GetSalary undefined(type Human has no filed or method GetSalary)
  52.         */
  53.         // human.GetSalary()
  54.         human.Work.GetSalary()
  55. }
复制代码
结果
  1. 结构体的实例为struct_knowledge.Human{Name:"", Age:0, Work:struct_knowledge.Worker{salary:20, profession:""}}
  2. 结构体的实例为struct_knowledge.Human{Name:"张三", Age:20, Work:struct_knowledge.Worker{salary:1000, profession:"no work"}}
  3. 结构体的实例为struct_knowledge.Human{Name:"lisa", Age:45, Work:struct_knowledge.Worker{salary:10000, profession:"waiter"}}
  4. 工资为10000
复制代码
访问规则

具名嵌套结构体的访问只能通过
  1. 嵌套结构体字段名.字段
  2. 嵌套结构体字段名.方法()
复制代码
不能通过最外层结构体直接访问。
举例
  1. type Worker struct{
  2.         salary int
  3.         profession string
  4. }
  5. //具名嵌套结构体
  6. type Human struct{
  7.         Name string
  8.         Age int
  9.         Work Worker
  10. }
复制代码
Human实例不能直接访问Worker实例的字段或方法,须要通过
  1. Human实例.Work.字段
  2. Human实例.Work.方法
复制代码
匿名结构体

根本语法

就是不写用字段汲取嵌套结构体而是直接写范例名,比方
  1. type 结构体类型A struct{
  2.     字段1 类型1
  3.     字段2 类型2
  4.     ...
  5. }
  6. type 结构体类型B struct{
  7.     字段1 类型1
  8.     结构体类型A
  9. }
复制代码
举例
  1. package struct_knowledge
  2. import "fmt"
  3. type StructA struct{
  4.         name string
  5.         age int
  6. }
  7. type StructB struct{
  8.         price int
  9.         StructA
  10. }
  11. func VisitStructB(){
  12.         var st StructB
  13.         fmt.Printf("嵌套结构体的值为%#v\n",st)
  14. }
复制代码
结果
  1. 嵌套结构体的值为struct_knowledge.StructB{price:0, StructA:struct_knowledge.StructA{name:"", age:0}}
复制代码
访问规则

名称访问

匿名结构体假如我们将他按照匿名字段明确,那么他就可以分析成如下情势:
  1. type 结构体类型A struct{
  2.     字段1 类型1
  3.     字段2 类型2
  4.     ...
  5. }
  6. type 结构体类型B struct{
  7.     字段1 类型1
  8.     结构体类型A
  9. }
  10. //按照匿名字段明确type 结构体范例B struct{    字段1 范例1    结构体A 结构体范例A}
复制代码
以是我们仍然可以通过如下情势修改和访问:
  1. 结构体B实例.结构体A.字段
  2. 结构体B实例.结构体A.方法()
复制代码
举例
  1. package struct_knowledge
  2. import "fmt"
  3. type StructA struct{
  4.         name string
  5.         age int
  6. }
  7. type StructB struct{
  8.         price int
  9.         StructA
  10. }
  11. /*
  12.         我们可以按照访问具名结构体的方法访问
  13.         匿名结构体的名字就是 类型同名
  14. */
  15. func VisitStructByName(){
  16.         var st StructB
  17.         //连锁访问
  18.         st.StructA.age = 25
  19.         fmt.Printf("结构体的实例为%#v\n",st)
  20.         //字面量访问
  21.         st = StructB{
  22.                 price: 1000,
  23.                 StructA: StructA{
  24.                         age:25,
  25.                         name:"lisi",
  26.                 },
  27.         }
  28.         fmt.Printf("结构体的实例为%#v\n",st)
  29.         //位置访问
  30.         st = StructB{
  31.                 1000,
  32.                 StructA{
  33.                         age:30,
  34.                         name:"sam",
  35.                 },
  36.         }
  37.         fmt.Printf("结构体的实例为%#v\n",st)
  38. }
复制代码
结果
  1. 结构体的实例为struct_knowledge.StructB{price:0, StructA:struct_knowledge.StructA{name:"", age:25}}
  2. 结构体的实例为struct_knowledge.StructB{price:1000, StructA:struct_knowledge.StructA{name:"lisi", age:25}}
  3. 结构体的实例为struct_knowledge.StructB{price:1000, StructA:struct_knowledge.StructA{name:"sam", age:30}}
复制代码
直接访问

匿名结构体与具名结构体最大的差异就是:
  1. 我们可以直接通过外层结构体访问匿名结构体的字段或方法(前提没有产生同名冲突)。
复制代码
举例
  1. package struct_knowledge
  2. import "fmt"
  3. type StructA struct{
  4.         name string
  5.         age int
  6. }
  7. type StructB struct{
  8.         price int
  9.         StructA
  10. }
  11. func (c StructA) GetAge(){
  12.         fmt.Printf("StructA的年龄为%v\n",c.age)
  13. }
  14. func VisitStructByNoName(){
  15.         var st StructB
  16.         //在不出现名字冲突的情况下,外层结构体可以直接访问匿名结构体的字段和方法
  17.         st.age = 25
  18.         st.GetAge()
  19.         fmt.Printf("结构体的实例为%#v\n",st)
  20.         //但仅限于这种成员访问,字面量和位置就不适用
  21.         /*
  22.                 报错:
  23.                 unknow field age in struct literal of type StructB
  24.                 unknow field name in struct literal of type StructB
  25.         */
  26.         // st = StructB{
  27.         //         price: 1000,
  28.         //         age:30,
  29.         //         name:"lisa",
  30.         // }
  31. }
复制代码
结果
  1. StructA的年龄为25
  2. 结构体的实例为struct_knowledge.StructB{price:0, StructA:struct_knowledge.StructA{name:"", age:25}}
复制代码
字段辩论

这种环境紧张出如今匿名结构体中,由于同一结构体中字段唯一,以是结构体中不能出现同名字段。
但是匿名结构体嵌套后,由于他可以匿名访问,以是就产生了字段和方法辩论。
这也是匿名结构体答应具名访问的缘故因由。
办理方案
当出现字段辩论时,访问匿名结构体的同名字段或方法须要接纳具名访问。
举例
  1. package struct_knowledge
  2. import "fmt"
  3. type StructOne struct{
  4.         name string
  5.         age int
  6.         price int
  7. }
  8. type StructTwo struct{
  9.         name string
  10.         age int
  11. }
  12. type StructThree struct{
  13.         name string
  14.         StructOne
  15.         StructTwo
  16. }
  17. func VisitStructThree(){
  18.         var st StructThree
  19.         fmt.Printf("结构体的实例为%#v\n",st)
  20.         //访问不同名字段,可以直接匿名访问
  21.         st.price  = 20
  22.         /*
  23.                 但是访问同名字段或方法,就需要指明结构体
  24.                 如果最外层结构体有就访问的是最外层
  25.         */
  26.         st.name = "lisa"
  27.         /*
  28.                 如果访问同名字段或方法,
  29.                 但最外层结构体也没有就会报错
  30.                 ambiguous selector st.age
  31.         */
  32.         // st.age = 25
  33. }
复制代码
结果
  1. 结构体的实例为struct_knowledge.StructThree{name:"", StructOne:struct_knowledge.StructOne{name:"", age:0, price:0}, StructTwo:struct_knowledge.StructTwo{name:"", age:0}}
  2. 结构体的实例为struct_knowledge.StructThree{name:"lisa", StructOne:struct_knowledge.StructOne{name:"", age:0, price:20}, StructTwo:struct_knowledge.StructTwo{name:"", age:0}}
复制代码
辩论字段访问规则

1.假如要访问的同名字段大概方法顶层有,直接访问则接纳顶层的字段或方法。
2.假如要访问的同名字段大概方法顶层没有,直接访问就会报错。
  1. # ambiguous的中文含义:模糊不清的,模棱两可的
  2. ambiguous selector st.xxx
复制代码
办理字段辩论标题

要访问嵌套结构体的同名字段大概方法,可以接纳具名访问法,比方
  1. 外层结构体实例.匿名结构体类型.字段
  2. 外层结构体实例.匿名结构体类型.方法()
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表