
go 语言支持通过嵌入(embedding)方式将一个接口的所有方法声明“继承”到另一个接口中,从而构建分层、可复用的接口契约,无需重复定义方法签名。
go 语言支持通过嵌入(embedding)方式将一个接口的所有方法声明“继承”到另一个接口中,从而构建分层、可复用的接口契约,无需重复定义方法签名。
在 Go 中,接口本身是纯契约定义,不包含实现,但其设计天然支持组合——这与结构体嵌入的语义高度一致。你无需使用关键字(如 extends 或 inherits),只需在接口定义中直接写入另一个接口类型名,即可完成方法集的合并。
例如,以下代码清晰展示了如何让 SpecificDatabase 接口自动包含 BasicDatabase 的全部方法:
type BasicDatabase interface {
CreateTable(name string) error
DeleteTable(name string) error
}
type SpecificDatabase interface {
BasicDatabase // ✅ 嵌入接口:等价于显式声明 CreateTable 和 DeleteTable
CreateUserRecord(user User) error
}此时,任何实现了 SpecificDatabase 的类型,必须同时实现:
- CreateTable(string) error
- DeleteTable(string) error
- CreateUserRecord(User) error
这意味着你可以安全地将 SpecificDatabase 类型作为参数传入期望 BasicDatabase 的函数中(协变兼容),也可在 SpecificDatabase 方法调用中直接使用 BasicDatabase 的方法,例如:
func setupDB(db SpecificDatabase) error {
if err := db.CreateTable("users"); err != nil { // ✅ 合法:嵌入后方法可用
return err
}
return db.CreateUserRecord(User{Name: "Alice"})
}⚠️ 注意事项:
- 接口嵌入仅是方法签名的扁平化合并,不引入任何运行时行为或字段;
- 嵌入多个接口时,若存在同名、同签名方法,不会冲突,而是自然统一为同一方法要求;
- 不支持“嵌入自身”或循环嵌入(如 A 嵌入 B,B 又嵌入 A),编译器会报错;
- 嵌入的接口可以是未导出的(小写首字母),但最终组合后的接口若需跨包使用,应确保所有嵌入接口及方法均为导出状态。
✅ 总结:Go 的接口嵌入是构建高内聚、低耦合抽象体系的核心机制。它鼓励按职责拆分基础接口(如 Reader、Writer、Closer),再通过组合形成领域专用接口(如 ReadWriteCloser),既保持简洁性,又极大提升接口的可测试性与可替换性。合理运用此特性,是编写地道 Go 代码的重要实践。










