go值接收者和指针接收者的区别

方法的接收者

package main

import (
	"fmt"
)

type Person struct {
	Name string
	Age int
}

func (p Person) walking(){
	fmt.Println("我是值类型方法")
	fmt.Printf("%s, 今年%d, 正在跑步\n", p.Name, p.Age)
}

func (p *Person) swimming(){
	fmt.Println("我是指针类型方法")
	fmt.Printf("%s, 今年%d, 正在游泳\n", p.Name, p.Age)
}


func main(){
	// 值类型既可以调用值接收者的方法也可以调用指针接收者的方法
	p := Person{
		Name: "lucy",
		Age: 25,
	}
	p.walking()

	p.swimming()

	// 指针类型既可以调用值接收者的方法也可以调用指针接收者的方法
	p1 := Person{
		Name: "Mike",
		Age: 21,
	}
	p1.walking()

	p1.swimming()
}

接口的实现,值类型接收者和指针接收者

package main

import (
	"fmt"
)

type Action interface {
	walking()
}

type Action1 interface{
	swimming()
}

type Person struct {
	Name string
	Age int
}

func (p Person) walking(){
	fmt.Println("我是接口值类型方法,可以值类型调用也可以指针类型调用")
	fmt.Printf("%s, 今年%d, 正在跑步\n", p.Name, p.Age)
}

func (p *Person) swimming(){
	fmt.Println("我是接口指针类型方法,只能指针类型调用")
	fmt.Printf("%s, 今年%d, 正在游泳\n", p.Name, p.Age)
}


func main(){
	var action Action
	// 值类型实现了接口的,指针类型和值类型都可以调用值类型的方法
	p := Person{
		Name: "lucy",
		Age: 25,
	}
	// action = p
	// action.walking()
	
	action = &p
	action.walking()



	// 指针类型实现了接口,只能指针类型可以调用指针类型的方法
	var action1 Action1
	p1 := Person{
		Name: "Mike",
		Age: 22,
	}
	// action1 = p1
	// action1.swimming() // 指针接收者不能用实现了接口的值类型调用,会报错

	action1 = &p1
	action1.swimming() // 指针接收者只能用实现了接口的指针类型调用

}

总结

方法接收者:
- 值类型,既可以调用值接收者的方法,也可以调用指针接收者的方法
- 指针类型,既可以调用指针接收者的方法,也可以调用值接收者的方法
但是接口的实现,值类型接收者和指针类型接收者不一样:
- 以值类型接收者实现接口,类型本身和该类型的指针类型,都实现了该接口
- 以指针类型接收者实现接口,只有对应的指针类型才被认为实现了接口
通常我们使用指针作为方法的接收者的利益:
- 使用指针方法能够修改接收者指向的值
- 可以避免在每次调用方法时复制该值,在值的类型为大型结构体时,这样做会更加高效
posted @ 2022-12-26 14:49  我在路上回头看  阅读(250)  评论(0编辑  收藏  举报