全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-14 7 分钟 ✍️ juanwangdev

Go方法集

方法集决定类型是否能满足特定接口,理解方法集是掌握接口的关键。

方法集定义

值类型方法集

Go
type User struct {
    Name string
}

// 值接收者方法
func (u User) GetName() string {
    return u.Name
}

// 指针接收者方法
func (u *User) SetName(name string) {
    u.Name = name
}

// 值类型User的方法集:只有值接收者方法
// User的方法集:{GetName}

指针类型方法集

Go
// 指针类型*User的方法集:包含所有方法
// *User的方法集:{GetName, SetName}

// 指针类型包含值接收者和指针接收者方法

方法集规则

核心规则

Go
类型T的方法集 = 所有接收者为T的方法
类型*T的方法集 = 所有接收者为T和*T的方法

规则详解

Go
type MyType struct{}

func (m MyType) ValueMethod() {}   // 值接收者
func (m *MyType) PointerMethod() {} // 指针接收者

// MyType方法集:{ValueMethod}
// *MyType方法集:{ValueMethod, PointerMethod}

接口满足规则

值类型与接口

Go
type Reader interface {
    Read() string
}

type MyReader struct{}

func (m MyReader) Read() string {
    return "data"
}

// MyReader有值接收者方法Read
// MyReader满足Reader接口 ✓
// *MyReader也满足Reader接口 ✓

var r Reader = MyReader{}   // ✓
var r Reader = &MyReader{}  // ✓

指针接收者方法

Go
type Writer interface {
    Write(data string)
}

type MyWriter struct{}

func (m *MyWriter) Write(data string) {
    // 指针接收者方法
}

// MyWriter方法集:{}(空)
// *MyWriter方法集:{Write}

// MyWriter不满足Writer接口 ✗
// *MyWriter满足Writer接口 ✓

var w Writer = MyWriter{}   // ✗ 编译错误
var w Writer = &MyWriter{}  // ✓

方法集对比表

接收者类型T方法集*T方法集T满足接口*T满足接口
值接收者
指针接收者
混合值方法全部值接口全部

方法集陷阱

指针接收者导致值不满足接口

Go
type Interface interface {
    Method()
}

type Impl struct{}

func (i *Impl) Method() {}  // 指针接收者

// 错误:值不满足接口
var x Interface = Impl{}  // 编译错误!

// 正确:指针满足接口
var x Interface = &Impl{}  // OK

解决方案

Go
// 方案1:使用指针
var x Interface = &Impl{}

// 方案2:改为值接收者
func (i Impl) Method() {}  // 值接收者

// 方案3:同时实现两种接收者
func (i Impl) Method() {}    // 值接收者
func (i *Impl) Method() {}   // 指针接收者(冗余)

方法集示例

Go
type Calculator interface {
    Calculate() int
    Reset()
}

type MyCalc struct {
    value int
}

func (m MyCalc) Calculate() int {
    return m.value  // 值接收者
}

func (m *MyCalc) Reset() {
    m.value = 0  // 指针接收者
}

// MyCalc方法集:{Calculate}
// *MyCalc方法集:{Calculate, Reset}

// MyCalc不满足Calculator接口(缺少Reset)
// *MyCalc满足Calculator接口

var c Calculator = &MyCalc{}  // ✓
// var c Calculator = MyCalc{}  // ✗

接口赋值规则

自动转换规则

text
type T struct{}

func (t T) M1() {}  // 值接收者
func (t *T) M2() {} // 指针接收者

var t T
var p = &t

// 调用方法时自动转换
t.M1()   // ✓ 值调用值方法
t.M2()   // ✓ 值调用指针方法(自动转为(&t).M2())
p.M1()   // ✓ 指针调用值方法(自动转为(*p).M1())
p.M2()   // ✓ 指针调用指针方法

// 但接口赋值不自动转换
// var i Interface = T{}  // 需要T方法集包含全部方法

要点总结

  • T方法集 = 值接收者方法
  • *T方法集 = 值接收者 + 指针接收者方法
  • 指针接收者方法:值类型不满足接口
  • 值接收者方法:值和指针都满足接口
  • 方法调用时自动转换,接口赋值不转换
  • 使用指针接收者时,接口赋值需用指针
  • 混合接收者时,指针类型方法集更完整

📝 发现内容有误?点击此处直接编辑

← 上一篇 Go方法定义与声明
下一篇 → Go空接口
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库