持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第45天,点击查看活动详情
一、注意事项
- 结构体可以使用嵌套匿名结构体所有的字段和方法,即:首字母大写或者小写的字段、方法,都可以使用。
- 匿名结构体字段访问可以简化
- 当结构体和匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,如希望访问匿名结构体的字段和方法,可以通过匿名结构体名来区分
- 结构体嵌入两个(或多个)匿名结构体,如两个匿名结构体有相同的字段和方法(同时结构体本身没有同名的字段和方法),在访问时,就必须明确指定匿名结构体名字,否则编译报错。
- 如果一个struct嵌套了一个有名结构体,这种模式就是组合,如果是组合关系,那么在访问组合的结构体的字段或方法时,必须带上结构体的名字
- 嵌套匿名结构体后,也可以在创建结构体变量(实例)时,直接指定各个匿名结构体字段的值。
二、案例演示
2.1 细节一
package main
import "fmt"
type A struct {
Name string
age int
}
func (a *A) SayOk() {
fmt.Println("A SayOK ", *a)
}
func (a *A) hello() {
fmt.Println("A hello ", *a)
}
type B struct {
A
}
func main() {
var b B
b.A.Name = "毕用欸"
b.A.age = 30
// A SayOK {毕用欸 30}
// A hello {毕用欸 30}
b.A.SayOk()
b.A.hello()
}
2.2 细节二
流程说明
- 直接通过b访问字段或方法时,其流程如下 b.Name
- 编译器先查看b对应的类型是否存在Name,如果有则直接调用B类型的Name字段
- 如果没有,去看B中嵌入匿名结构体中是否存在Name字段,如果有就调用,如果没有,就查找匿名结构体中的匿名结构体,如果都没有找到,则会报错
package main
import "fmt"
type A struct {
Name string
age int
}
func (a *A) SayOk() {
fmt.Println("A SayOK ", *a)
}
func (a *A) hello() {
fmt.Println("A hello ", *a)
}
type B struct {
A
}
func main() {
var b B
b.A.Name = "毕用欸"
b.A.age = 30
// A SayOK {毕用欸 30}
// A hello {毕用欸 30}
b.A.SayOk()
b.A.hello()
fmt.Println()
// 简化语法
b.Name = "毕用欸"
b.age = 30
// A SayOK {毕用欸 30}
// A hello {毕用欸 30}
b.SayOk()
b.hello()
}
2.3 细节三
package main
import "fmt"
type A struct {
Name string
age int
}
func (a *A) SayOk() {
fmt.Println("A SayOK ", *a)
}
func (a *A) hello() {
fmt.Println("A hello ", *a)
}
// 案例三
type B struct {
A
Name string
}
func (b *B) SayOK() {
fmt.Println("B SayOK", b.Name)
}
func main() {
var b B
b.Name = "bob"
b.age = 100
// B SayOK bob
// A hello { 100}
b.SayOK()
b.hello()
// 若想给A的Name赋值,那么需要如下
// A hello {Aliy 100}
b.A.Name = "Aliy"
b.hello()
}
2.4 细节四
package main
type A struct {
Name string
age int
}
type B struct {
Name string
}
// 案例四
type C struct {
A
B
}
func main() {
var c C
// 如果 C 没有Name字段,A和B有Name,必须通过指定匿名结构体名来区分
c.A.Name = "AAAAA"
c.B.Name = "BBBBB"
}
2.5 细节五
package main
type A struct {
Name string
age int
}
type B struct {
a A
}
func main() {
var b B
// 嵌套有名结构体
b.a.Name = "c-----AAAAAA"
}
2.6 细节六
package main
import "fmt"
type Goods struct {
Name string
Price float64
}
type Brand struct {
Name string
Add string
}
type TV struct {
Goods
Brand
}
type TVPtr struct {
*Goods
*Brand
}
func main() {
tv := TV{Goods{"电视机", 1999}, Brand{"小米", "China"}}
// {{电视机 1999} {小米 China}}
fmt.Println(tv)
tv2 := TV{
Goods{
Name: "4K电视机",
Price: 4999,
},
Brand{
Name: "索尼",
Add: "日本",
},
}
// TV2 ===> {{4K电视机 4999} {索尼 日本}}
fmt.Println("TV2 ===> ", tv2)
fmt.Println()
// 使用指针方法
tv3 := TVPtr{
&Goods{
Name: "4K电视机",
Price: 4999,
},
&Brand{
Name: "三星",
Add: "韩国",
},
}
// TVPtr ====> {4K电视机 4999} {三星 韩国}
fmt.Println("TVPtr ====> ", *tv3.Goods, *tv3.Brand)
}