
go 不支持传统继承,但可通过嵌入空结构体的方式让多个结构体共享同一组方法,避免重复实现,同时保持类型独立性和内存布局高效性。
在 Go 中,若多个结构体(如 A 和 B)需共用相同行为(例如 SayHi()),又不想为每个类型单独重写方法,最简洁、地道的解决方案是 使用结构体嵌入(embedding)配合匿名字段。
核心思路是:将通用方法定义在独立的“工具结构体”上,再将其作为匿名字段嵌入目标结构体。Go 会自动提升(promote)嵌入字段的导出方法,使外层结构体直接可调用。
✅ 正确示例:
package main
import "fmt"
// 定义通用行为载体(空结构体,零内存开销)
type Speaker struct{}
func (s Speaker) SayHi() {
fmt.Println("hi!")
}
// A 和 B 均嵌入 Speaker,无需额外字段或逻辑
type A struct {
Speaker
}
type B struct {
Speaker
}
func main() {
a := A{}
a.SayHi() // 输出: hi!
b := B{}
b.SayHi() // 输出: hi!
}⚠️ 注意事项:
- 嵌入字段必须是导出类型(首字母大写),否则其方法不会被提升;
- Speaker 是空结构体(struct{}),不增加任何内存占用,且无状态依赖,适合纯行为复用;
- 若方法需访问外层结构体的字段(如 a.Name),则无法仅靠嵌入解决——此时应将公共逻辑提取为独立函数,再由各类型方法调用:
func sayHiImpl(name string) {
fmt.Printf("hi, %s!\n", name)
}
func (a A) SayHi() { sayHiImpl(a.Name) }
func (b B) SayHi() { sayHiImpl(b.Nickname) }? 总结:Go 中“方法复用”不依赖继承或接口实现,而依赖组合(composition)与嵌入机制。优先选择嵌入空结构体;当方法需感知接收者状态时,辅以共享辅助函数——这正是 Go “组合优于继承”哲学的典型实践。










