
一、Go 方法核心概念1. 方法本质方法本质是函数但必须和特定类型绑定区别于普通函数是 Go 实现面向对象封装的核心手段。2. 函数 vs 方法 语法对比go// 1. 普通函数无类型绑定 func 函数名(参数) 返回值 {} // 2. 匿名函数 func() {} // 3. 方法绑定指定类型必须有接收者 func (接收者变量 绑定类型) 方法名(参数) 返回值 {}接收者相当于方法的第一个参数是绑定类型的实例只有绑定了类型的函数才能叫方法3. 方法的意义实现封装普通函数没有 归属方法可以给类型绑定专属函数就像机器的按钮隐藏内部实现对外提供操作接口。二、方法基础使用1. 给自定义类型绑定方法gopackage main import fmt // 自定义类型 type long int // 普通函数面向过程 func Add01(a, b long) long { return a b } // 方法给long类型绑定面向对象 // tmp接收者相当于参数 func (tmp long) Add02(other long) long { return tmp other } func main() { // 调用普通函数 res1 : Add01(1, 1) fmt.Println(函数调用, res1) // 调用方法变量名.方法名() var a long 2 res2 : a.Add02(3) fmt.Println(方法调用, res2) }核心面向对象只是换了一种调用方式本质还是函数。2. 给结构体类型绑定方法最常用结构体是 Go 中最常用的绑定类型可实现属性 方法的封装gotype Person struct { name string sex byte age int } // 绑定打印方法 func (tmp Person) PrintInfo() { fmt.Println(成员信息, tmp) } // 绑定赋值方法 func (p *Person) SetInfo(n string, s byte, a int) { p.name n p.sex s p.age a } func main() { // 初始化结构体 p : Person{mike, m, 18} p.PrintInfo() // 调用方法 // 指针接收者方法调用 var p2 Person (p2).SetInfo(yoyo, f, 22) p2.PrintInfo() }三、方法使用规则1. 接收者类型限制接口类型不能作为接收者接收者的基础类型本身不能是指针go// 错误写法类型本身是指针不能做接收者 type pointer *int func (tmp pointer) test() {} // 正确写法接收者是指针类型推荐 type long int func (tmp *long) test02() {}2. 不支持重载支持同名方法Go不支持函数重载但接收者类型不同同名方法不算重载是独立方法gotype long int type char string // 两个test方法接收者不同相互独立 func (tmp long) test() {} func (tmp char) test() {}四、值接收者 vs 指针接收者核心重点1. 本质区别值传递 vs 指针传递类型传递方式效果使用场景值接收者值拷贝方法内修改不影响原变量只读操作、小型结构体指针接收者引用传递方法内修改直接修改原变量修改成员、大型结构体、提升效率2. 代码示例gotype Person struct { name string age int } // 值接收者值传递拷贝副本 func (p Person) SetInfoValue(n string, a int) { p.name n p.age a } // 指针接收者引用传递操作原变量 func (p *Person) SetInfoPointer(n string, a int) { p.name n p.age a } func main() { s1 : Person{go, 22} // 值接收者不修改原变量 s1.SetInfoValue(mike, 18) fmt.Println(s1) // 输出{go 22} // 指针接收者修改原变量 (s1).SetInfoPointer(mike, 18) fmt.Println(s1) // 输出{mike 18} }五、方法集自动类型转换Go 编译器会自动转换接收者类型无需严格遵守方法集约束指针类型变量可以调用值接收者 指针接收者方法普通类型变量可以调用值接收者 指针接收者方法gotype Person struct { name string } func (p Person) SetInfoValue() {} // 值接收者 func (p *Person) SetInfoPointer() {} // 指针接收者 func main() { // 指针变量调用两种方法 p1 : Person{mike} p1.SetInfoValue() p1.SetInfoPointer() // 普通变量调用两种方法 p2 : Person{mike} p2.SetInfoValue() p2.SetInfoPointer() // 编译器自动转换为 (p2).SetInfoPointer() }六、方法的继承与重写1. 方法继承通过匿名字段实现结构体嵌套匿名结构体自动继承匿名结构体的所有成员和方法go// 父结构体 type Person struct { name string age int } // 父结构体方法 func (tmp *Person) PrintInfo() { fmt.Printf(姓名%s年龄%d\n, tmp.name, tmp.age) } // 子结构体嵌套Person匿名字段实现继承 type Student struct { Person // 匿名字段 id int addr string } func main() { s : Student{Person{mike, 18}, 666, 北京} s.PrintInfo() // 直接调用继承的方法 }2. 方法重写就近原则子结构体定义和父结构体同名的方法就是方法重写调用时优先调用自身方法就近原则强制调用父类方法子变量.父结构体.方法()go// 子结构体重写方法 func (tmp *Student) PrintInfo() { fmt.Println(学生信息, tmp) } func main() { s : Student{Person{mike, 18}, 666, 北京} // 就近原则调用子结构体方法 s.PrintInfo() // 显式调用父结构体方法 s.Person.PrintInfo() }七、方法值 方法表达式1. 方法值将方法赋值给变量隐藏接收者直接调用变量即可gofunc main() { p : Person{mike, 18} // 传统调用 p.SetInfoPointer() // 方法值绑定接收者直接调用 pFunc : p.SetInfoPointer pFunc() // 等价于 p.SetInfoPointer() vFunc : p.SetInfoValue vFunc() }2. 方法表达式显式传递接收者格式(类型).方法名gofunc main() { p : Person{mike, 18} // 指针接收者方法表达式 f1 : (*Person).SetInfoPointer f1(p) // 显式传接收者 // 值接收者方法表达式 f2 : (Person).SetInfoValue f2(p) }八、核心总结方法 绑定类型的函数是 Go 封装的核心接收者是方法第一个参数值接收者拷贝副本不修改原变量指针接收者引用传递修改原变量编译器自动转换接收者类型方法集无严格调用限制匿名字段实现方法继承同名方法实现方法重写就近原则方法值 / 表达式简化方法调用灵活使用