classstruct值参数指针参数
func(receiver Type) Method
func(receiver *Type) Method
值对象可以调用值方法&指针方法
type Person struct{
	Name string 
	Age int 
}
// 值方法
func(p Person) SayHello(){
	fmt.Printf("Hello, my name is %s\n", p.Name)
}
// 引用方法
func(p *Person) SetAge(age int){
	p.Age = age
}

func main(){
	var jack = Person{"jack", 10}
	jack.SayHello()
	jack.SetAge(20)
	fmt.Println(jack.Age)  // 20
}
jack.SetAge(&jack).SetAge
指针对象可以调用值方法&指针方法
type Person struct{
	Name string 
	Age int 
}
// 值方法
func(p Person) SayHello(){
	fmt.Printf("Hello, my name is %s\n", p.Name)
}
// 引用方法
func(p *Person) SetAge(age int){
	p.Age = age
}

func main(){
	var jack = &Person{"jack", 10}
	jack.SayHello()
	jack.SetAge(20)
	fmt.Println(jack.Age)  // 20
}
jack.SayHello(*jack).SayHello

如果我们调用一个接口里面的函数,结构体对象实现接口时的方法可能是指针方法也可以是值方法,那么需要注意:

值类型只能调用值方法指针类型可以调用值方法和指针方法

下面的例子说明了这个问题

package main 

import (
	"fmt"
)
// 接口类型
type Human interface{
	SayHello()
	SetAge(age int)
	GetAge()int 
}
// 结构体对象
type Person struct{
	Name string 
	Age int 
}
// 值方法
func(p Person) SayHello(){
	fmt.Printf("Hello, my name is %s\n", p.Name)
}
// 指针方法
func(p *Person) SetAge(age int){
	p.Age = age
}
// 值方法
func(p Person)GetAge()int{
	return p.Age
}

func main(){
	// jack是个接口,被一个指针对象赋值,下面的方法都可以正确执行
	var jack Human  // 声明一个接口类型的对象
	jack = &Person{"jack", 10} // Person实现了接口
	jack.SayHello() 
	jack.SetAge(20)
	fmt.Println(jack.GetAge())

	// 值类型并没有实现SetAge的方法,所以赋值的时候会报错
	// cannot use Person literal (type Person) as type Human in assignment:
    //    Person does not implement Human (SetAge method has pointer receiver)
	var Tom Human 
	Tom = Person{"Tom", 12}
	Tom.SayHello()
	Tom.SetAge(10)
	fmt.Println(Tom.GetAge())
}

那么什么时候使用指针方法,什么时候使用值方法呢,可以考虑:

复制成本将不可忽略不应该被复制