匿名组合=匿名字段
代码复用
- 匿名函数
- 结构体类型定义
匿名字段
用于结构体,很像嵌套结构体,目标是代码复用,减少冗余,也就是“继承”
定义
一般情况下,定义结构体的时候是字段名与其类型一一对应,实际上Go支持只提供类型,
而不写字段名的方式,也就是匿名字段,也称为嵌入字段。
当匿名字段也是一个结构体的时候,那么这个结构体所拥有的全部字段都被隐式地引入了当
前定义的这个结构体。
理论上可以无限嵌套下去,但不建议,因为赋值的时候会很麻烦
初始化
key:按序赋值
可以指定成员初始化,其他自动赋值为0,方法和结构体的一样字段名:值
,需要一一对应
package main
import "fmt"
func main() {
type person struct {
name string
age int
}
type person_1 struct{
person
love string
hate string
}
man_1 :=person_1{
person{"justin",25},
"girl", "bad luck",
}
fmt.Println(man_1)
fmt.Printf("%v\n", man_1)
fmt.Printf("%+v\n", man_1)
}
NOTE:
可以使用new函数进行初始化, 但由于嵌套形态不一, 并不推荐
调用
:::info
:::
打印
println(man_1)
- printf
printf("%v",man_1)
和println(man_1)
效果相同printf("%+v",man_1)
会打印出更详细的信息
:::info
:::
赋值
.
成员运算符- 和结构体一样,
man_1.name
,
匿名字段部分亦可直接调用,无需man_1.person.name
(除非同名字段) - 匿名字段还可以整体赋值,
man_1.person = person{...}
- 和结构体一样,
- 统一赋值
等式右边——person_1{...}
:::info 同名字段
:::
同名字段
key:默认就近原则
若需要赋值匿名字段的同名字段,则需要man_1.person.age
这里揭示了成员运算符的机制
- 先在本作用域,搜索字段,索不到,再在匿名字段里搜索,无需码农再加匿名字段
- 同名字段,遵循就近原则;若需要赋值匿名字段的同名字段,则需要加上匿名字段
应用
非结构体匿名字段
结构体中,只写类型,不写名,比如图中基础类型的匿名字段
- 初始化依旧
- 成员运算符怎么弄呢?——
s.int
直接写类型名
结构体指针类型的匿名字段
本质上,和原来的结构体指针没差别,我们下面来看一些语法上的操作
- 结构体就加个
*
- 初始化
- 直接赋值
结果 - 先分配空间,等式右边——
new(person)
/Person{}
- 直接赋值
综合
- 结构体定义进行继承,
- 结构体成员访问也就继承了
- 方法就带着进行继承
- 接口的定义继承了,方法也就带着继承了