跳到主要内容

类型嵌入与方法提升

什么是方法提升? 嵌入字段名如何确定?​

  • embedded type: struct 嵌入字段的方法可提升到外层类型;
  • 方法提升: 外层值可直接调用嵌入字段的方法;
  • 嵌入字段名: 默认使用类型名;
package main

type Logger struct{}

func (Logger) Log() {
println("log")
}

type Service struct {
Logger // 嵌入字段,字段名默认是类型名 Logger
}

func main() {
s := Service{}
s.Log() // 方法提升,等价于 s.Logger.Log()
s.Logger.Log() // 显式通过嵌入字段调用
}

选择器歧义从何而来? 如何消除?​

  • 冲突来源: 选择器优先选择最浅层匹配;同一最浅层存在多个同名字段或方法时才产生歧义;
  • 消除歧义: 显式选择具体嵌入字段;
type Metrics struct{}

func (Metrics) Log() {
println("metrics")
}

type App struct {
Logger // Logger 有 Log 方法
Metrics // Metrics 也有 Log 方法
}

func main() {
a := App{}
// a.Log() // 报错:Logger.Log 与 Metrics.Log 同名,选择器歧义
a.Logger.Log() // 明确选择 Logger 的 Log 方法
a.Metrics.Log() // 明确选择 Metrics 的 Log 方法
}