浅谈Golang T和*T方法集的关系

四种调用场景

接口传值,调用值接收者

package main

type Iface interface {
    
    
	hello()
}
type Stu struct {
    
    
}

func (c Stu) hello() {
    
    
	panic("implement me")
}
func main(){
    
    
	var IfTs Iface
	var stu Stu
	IfTs=stu
	IfTs.hello()
}

接口传指针,调用指针接收者

package main

type Iface interface {
    
    
	hello()
}
type Stu struct {
    
    
}

func (c *Stu) hello() {
    
    
	panic("implement me")
}
func main(){
    
    
	var IfTs Iface
	var stu Stu
	IfTs=&stu
	IfTs.hello()
}

接口传指针,调用值接收者(success)

package main

type Iface interface {
    
    
	hello()
}
type Stu struct {
    
    
}

func (c Stu) hello() {
    
    
	panic("implement me")
}
func main(){
    
    
	var IfTs Iface
	var stu Stu
	IfTs=&stu
	IfTs.hello()
}

接口传值,调用指针接收者(error)

package main

type Iface interface {
    
    
	hello()
}
type Stu struct {
    
    
}

func (c *Stu) hello() {
    
    
	panic("implement me")
}
func main(){
    
    
	var IfTs Iface
	var stu Stu
	IfTs=stu//err
	IfTs.hello()
}

在这里插入图片描述

原因剖析

在这里插入图片描述

首先要明确一点,T和*T是两种不同的类型。

在这里插入图片描述
那为什么第三种情况可以正常运行呢?通过*T类型的变量调用T类型的接收者的方法,只是一种语法糖,编译器会在调用端进行指针解引用。

那为什么第四种情况会err呢?因为*T和T是两种不同的类型,这里没有语法糖,T类型没有实现接口的方法,自然会err咯。无法将’stu’ (类型Stu)用作类型Iface类型,未实现’Iface’

总结

因为通过 *T 类型的变量调用T类型的接收者的方法,是一种语法糖,所以可以简单的理解为 *T 的方法集包括了所有的T方法集,这也就是为什么会有人说,只要接收者里面有一个是指针接收者,那就把所有的方法接收者都改为指针接收者的原因了。不过需要注意的是T和 *T 是两种不同的类型!

猜你喜欢

转载自blog.csdn.net/qq_42956653/article/details/121316672