环境

Windows 10
golang 1.17

前言
valueAddAgeptrAddAge
代码
package main

import "fmt"

type Person struct {
	age int
}

// 值方法
func (p Person) valueAddAge() {
	p.age++
}

// 指针方法
func (p *Person) ptrAddAge() {
	p.age++
}

func main() {
	// p1是值类型,调用值方法
	p1 := Person{age: 18}
	p1.valueAddAge()
	fmt.Println(p1.age) // 输出18,没有改变

	// p2是值类型,调用指针方法
	p2 := Person{age: 18}
	p2.ptrAddAge()
	fmt.Println(p2.age) // 输出19,有改变

	// p3是指针类型,调用值方法
	p3 := &Person{age: 18}
	p3.valueAddAge()
	fmt.Println(p3.age) // 输出18,没有改变

	// p4是指针类型,调用指针方法
	p4 := &Person{age: 18}
	p4.ptrAddAge()
	fmt.Println(p4.age) // 输出19,有改变
}

p1p2p3p4
p2p3p2.ptrAddAge()(&p2).ptrAddAge()p2
p2
p3.valueAddAge()(*p3).valueAddAge()p3

如果调用者是指针类型,我们知道,即使将指针复制一份,它指向的原始数据还是不变的,因此在方法中对调用者的数据进行修改,是会影响到调用者的;

但是如果调用者是值类型的,值类型的变量被复制了一份,那新的变量就不是原来的那个变量了,因此在方法里对新变量做修改,是不会影响到原调用者的。

结论

值方法指针方法 的区别,就是看方法里的操作是否会影响到调用者。值方法不会影响,指针方法会影响。

其它:与interface接口组合使用
调用者接收者interface
package main

import "fmt"

// Human接口
type Human interface {
	getAge() int
}

// Person结构体
type Person struct {
	age int
}

// 实现Human接口的getAge方法,接收者是指针类型
func (rec *Person) getAge() int {
	return rec.age
}

func main() {
	// 创建一个Person对象,值类型
	p1 := Person{age: 18}
	// 把p1赋值给一个类型为Human的接口变量
	var ivar Human = p1 // 这一行会报编译错误
}

p1ivarp1Human

什么是方法集?简单来说就是:

p1p1
p1Human
参考