[Go语言基础问题]为什么声明在指针上的方法可以通过地址变量赋值给对应的接口?

1. 运行环境

go version go1.19 windows/amd64

2. 问题描述?

我理解在Go语言中,通过原始类型的变量调用声明在指针类型上的方法或者通过指针变量调用声明在原始类型上的方法实际上是Go的语法糖,但是有这么一条规则我在学习的时候一直没理解原因是什么。
如下代码所示,我将T类型的变量t赋值给I接口类型的变量i是不可以的,因为t没有实现M方法,很好理解

package main

type T int
type I interface {
    M()
}

func (t *T) M() {}

func main() {
    var t T
    var i I
    i = t //无法赋值,提示t未实现M方法
}

但是为什么反过来,如果方法是声明在T类型上,赋值时使用指针就可以了

package main

type  T  int

type  I  interface {

 M()

}

func (t T) M() {}

func  main() {

 var  t T

 var  i I

 i = &t //这是可以赋值,但是&t也没有实现M方法呀

}
最佳答案

www.bilibili.com/video/BV1NK4y137P...

有个视频讲解得很细,可以了解下

1年前 评论
eddy94 (楼主) 1年前
讨论数量: 11
╰ゝSakura

你的代码居然不报 i declared but not used ?

1年前 评论
╰ゝSakura

这样子说吧,如果你的interface是非指针类型的话,对应的调用方式是支持指针类型和非指针类型,go语法支持的。 但是你如果指定了指针类型,那么你的调用方式是只支持指针类型 可运行代码如下:

package main

type T int
type I interface {
    M()
}

func (t *T) M() {}

func main() {
    var t T
    i := &t 
    i.M()
}
1年前 评论
eddy94 (楼主) 1年前
╰ゝSakura

file go语言圣经多翻翻

1年前 评论
eddy94 (楼主) 1年前

1.这里是因为 go 编译器会为T.M() (值类型方法),添加包装方法 *T.M(), 所以当 T 为值类型时,可以理解成它即通过值类型实现该接口,也通过指针类型实现了接口(编译器所为)
2.指针类型方法,编译器不会进行处理,所以只有指针类型实现了该接口,值类型并没有实现

以上是我个人理解哈,如果想 go 进阶,可以搜下【幼麟实验室】个人觉得还是这个说不错

1年前 评论
eddy94 (楼主) 1年前
eddy94 (楼主) 1年前

www.bilibili.com/video/BV1NK4y137P...

有个视频讲解得很细,可以了解下

1年前 评论
eddy94 (楼主) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!