马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
结构体嵌套
golang中没有类,他通过结构体来实现其他编程语言中类的相干功能。
具名结构体
根本语法
根本语法
golang的结构体嵌套特殊简单。- type 结构体类型1 struct{
- 字段 类型1
- 字段 类型2
- }
- //这样就实现了结构体的嵌套
- type 结构体类型2 struct{
- 字段 类型1
- 字段 类型2
- 字段 结构体类型1
- }
复制代码 举例- package struct_knowledge
- import "fmt"
- type Worker struct{
- salary int
- profession string
- }
- //具名嵌套结构体
- type Human struct{
- Name string
- Age int
- Work Worker
- }
- func (w Worker) GetSalary(){
- fmt.Printf("工资为%d\n",w.salary)
- }
- //访问具名结构体
- func VisitNestingStruct(){
- var human Human
-
- //访问字段
- /*
- 报错:human.salary undefined(type Human has no filed or method GetSalary)
- */
- //human.salary = 25
-
- //通过字段连锁访问
- human.Work.salary = 20
- fmt.Printf("结构体的实例为%v\n",human)
- //通过字面量访问
- human = Human{
- Age: 20,
- Name: "张三",
- Work: Worker{
- salary: 1000,
- profession: "no work",
- },
- }
- fmt.Printf("结构体的实例为%v\n",human)
- //通过位置赋值
- human = Human{
- "lisa",
- 45,
- Worker{
- salary: 10000,
- profession: "waiter",
- },
- }
- fmt.Printf("结构体的实例为%v\n",human)
- // 调用方法
- /*
- 报错:human.GetSalary undefined(type Human has no filed or method GetSalary)
- */
- // human.GetSalary()
- human.Work.GetSalary()
- }
复制代码 结果- 结构体的实例为struct_knowledge.Human{Name:"", Age:0, Work:struct_knowledge.Worker{salary:20, profession:""}}
- 结构体的实例为struct_knowledge.Human{Name:"张三", Age:20, Work:struct_knowledge.Worker{salary:1000, profession:"no work"}}
- 结构体的实例为struct_knowledge.Human{Name:"lisa", Age:45, Work:struct_knowledge.Worker{salary:10000, profession:"waiter"}}
- 工资为10000
复制代码 访问规则
具名嵌套结构体的访问只能通过不能通过最外层结构体直接访问。
举例- type Worker struct{
- salary int
- profession string
- }
- //具名嵌套结构体
- type Human struct{
- Name string
- Age int
- Work Worker
- }
复制代码 Human实例不能直接访问Worker实例的字段或方法,须要通过- Human实例.Work.字段
- Human实例.Work.方法
复制代码 匿名结构体
根本语法
就是不写用字段汲取嵌套结构体而是直接写范例名,比方- type 结构体类型A struct{
- 字段1 类型1
- 字段2 类型2
- ...
- }
- type 结构体类型B struct{
- 字段1 类型1
- 结构体类型A
- }
复制代码 举例- package struct_knowledge
- import "fmt"
- type StructA struct{
- name string
- age int
- }
- type StructB struct{
- price int
- StructA
- }
- func VisitStructB(){
- var st StructB
- fmt.Printf("嵌套结构体的值为%#v\n",st)
- }
复制代码 结果- 嵌套结构体的值为struct_knowledge.StructB{price:0, StructA:struct_knowledge.StructA{name:"", age:0}}
复制代码 访问规则
名称访问
匿名结构体假如我们将他按照匿名字段明确,那么他就可以分析成如下情势:- type 结构体类型A struct{
- 字段1 类型1
- 字段2 类型2
- ...
- }
- type 结构体类型B struct{
- 字段1 类型1
- 结构体类型A
- }
- //按照匿名字段明确type 结构体范例B struct{ 字段1 范例1 结构体A 结构体范例A}
复制代码 以是我们仍然可以通过如下情势修改和访问:- 结构体B实例.结构体A.字段
- 结构体B实例.结构体A.方法()
复制代码 举例- package struct_knowledge
- import "fmt"
- type StructA struct{
- name string
- age int
- }
- type StructB struct{
- price int
- StructA
- }
- /*
- 我们可以按照访问具名结构体的方法访问
- 匿名结构体的名字就是 类型同名
- */
- func VisitStructByName(){
- var st StructB
- //连锁访问
- st.StructA.age = 25
- fmt.Printf("结构体的实例为%#v\n",st)
- //字面量访问
- st = StructB{
- price: 1000,
- StructA: StructA{
- age:25,
- name:"lisi",
- },
- }
- fmt.Printf("结构体的实例为%#v\n",st)
- //位置访问
- st = StructB{
- 1000,
- StructA{
- age:30,
- name:"sam",
- },
- }
- fmt.Printf("结构体的实例为%#v\n",st)
- }
复制代码 结果- 结构体的实例为struct_knowledge.StructB{price:0, StructA:struct_knowledge.StructA{name:"", age:25}}
- 结构体的实例为struct_knowledge.StructB{price:1000, StructA:struct_knowledge.StructA{name:"lisi", age:25}}
- 结构体的实例为struct_knowledge.StructB{price:1000, StructA:struct_knowledge.StructA{name:"sam", age:30}}
复制代码 直接访问
匿名结构体与具名结构体最大的差异就是:- 我们可以直接通过外层结构体访问匿名结构体的字段或方法(前提没有产生同名冲突)。
复制代码 举例- package struct_knowledge
- import "fmt"
- type StructA struct{
- name string
- age int
- }
- type StructB struct{
- price int
- StructA
- }
- func (c StructA) GetAge(){
- fmt.Printf("StructA的年龄为%v\n",c.age)
- }
- func VisitStructByNoName(){
- var st StructB
- //在不出现名字冲突的情况下,外层结构体可以直接访问匿名结构体的字段和方法
- st.age = 25
- st.GetAge()
- fmt.Printf("结构体的实例为%#v\n",st)
- //但仅限于这种成员访问,字面量和位置就不适用
- /*
- 报错:
- unknow field age in struct literal of type StructB
- unknow field name in struct literal of type StructB
- */
- // st = StructB{
- // price: 1000,
- // age:30,
- // name:"lisa",
- // }
- }
复制代码 结果- StructA的年龄为25
- 结构体的实例为struct_knowledge.StructB{price:0, StructA:struct_knowledge.StructA{name:"", age:25}}
复制代码 字段辩论
这种环境紧张出如今匿名结构体中,由于同一结构体中字段唯一,以是结构体中不能出现同名字段。
但是匿名结构体嵌套后,由于他可以匿名访问,以是就产生了字段和方法辩论。
这也是匿名结构体答应具名访问的缘故因由。
办理方案
当出现字段辩论时,访问匿名结构体的同名字段或方法须要接纳具名访问。
举例- package struct_knowledge
- import "fmt"
- type StructOne struct{
- name string
- age int
- price int
- }
- type StructTwo struct{
- name string
- age int
- }
- type StructThree struct{
- name string
- StructOne
- StructTwo
- }
- func VisitStructThree(){
- var st StructThree
- fmt.Printf("结构体的实例为%#v\n",st)
- //访问不同名字段,可以直接匿名访问
- st.price = 20
- /*
- 但是访问同名字段或方法,就需要指明结构体
- 如果最外层结构体有就访问的是最外层
- */
- st.name = "lisa"
- /*
- 如果访问同名字段或方法,
- 但最外层结构体也没有就会报错
- ambiguous selector st.age
- */
- // st.age = 25
- }
复制代码 结果- 结构体的实例为struct_knowledge.StructThree{name:"", StructOne:struct_knowledge.StructOne{name:"", age:0, price:0}, StructTwo:struct_knowledge.StructTwo{name:"", age:0}}
- 结构体的实例为struct_knowledge.StructThree{name:"lisa", StructOne:struct_knowledge.StructOne{name:"", age:0, price:20}, StructTwo:struct_knowledge.StructTwo{name:"", age:0}}
复制代码 辩论字段访问规则
1.假如要访问的同名字段大概方法顶层有,直接访问则接纳顶层的字段或方法。
2.假如要访问的同名字段大概方法顶层没有,直接访问就会报错。- # ambiguous的中文含义:模糊不清的,模棱两可的
- ambiguous selector st.xxx
复制代码 办理字段辩论标题
要访问嵌套结构体的同名字段大概方法,可以接纳具名访问法,比方- 外层结构体实例.匿名结构体类型.字段
- 外层结构体实例.匿名结构体类型.方法()
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |