持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第25天,点击查看活动详情
struct 实现对象
众所周知,Go 没有对象的和继承的概念,但还是很严格的遵循面向对象的原则。其中可以使用 Struct 和方法来模拟对象。设计原则上组合优于继承,使用 Struct 嵌套实现组合。
type Car struct {
}
func (c Car) handler(){
fmt.Println("car")
}
以上代码就是简单的的一个 Car 对象和 Car 方法。
Golang 允许在 struct 中组合其他的 strcut 。 有两种组合结构的方式:匿名字段和显式字段。
匿名嵌入字段
匿名字段是没有显式字段名称的结构字段,即在 struct 中嵌入匿名的字段。当前的 struct 也是可以访问匿名字段的 struct 的所有方法和属性。 这些方法和属性称为“提升”方法和属性。 匿名嵌入字段也可以通过类型名直接访问。
type Vehicle struct {
Car
}
v:=Vehicle{name:"xiaojiaoche"}
v.handler(); // 直接访问其方法
v.Car.handler();//通过嵌入字段访问
从以上代码可以看到,可以直接调用匿名嵌入的方法,也可以通过类型名直接访问,得到结果都是一样的。但是如果 Vehicle 结构也实现了方法时,结果就会不一样了。
func (v Vehicle) handler(){
fmt.Println("vehicle")
}
v.handler() // vehicle
v.Car.handler() // car
可以看到直接调用方法时输出的是当前结构体的绑定的方法,所以嵌入结构中的方法和属性被“隐藏”。但仍可以通过专门访问嵌入字段然后调用方法或属性来访问隐藏的方法和属性。
显式字段
通过使用显式命名字段可以避免与提升和隐藏字段混淆。
type Vehicle struct {
c Car
}
func (v Vehicle) handler(){
fmt.Println("vehicle")
}
v := Vehicle{name:"smallCar"}
v.handler() // 输出结果 vehicle
v.c.handler() // 输出结果 car
v.Car.handler() // error
所以,如果要调用 Car 的 handler() 方法,必须使用 .c 显式访问嵌套的 Car 对象。 不再可能访问基础 .Car 字段。
结论
综上所述,Golang 中结构体的组合方式有两种:匿名嵌入字段和显式字段。
- 匿名嵌入字段:1、可直接访问嵌套 struct 的方法和属性;2、如果嵌套结构声明了同名属性的方法,则这些方法和属性可能会被隐藏。
- 显示字段:字段和嵌套的结构相关联,访问嵌套结构的方法和属性都是明确字段的