小白关于接口的一个问题

YerdGu · 2018-07-08 15:44:52 · 952 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2018-07-08 15:44:52 的主题,其中的信息可能已经有所发展或是发生改变。

type Itest interface { SayHello() }

var G_Test Itest

type TestS struct { id_ int }

func (ts TestS)SayHello() { ts.id_ = 1 }

type TestP struct { id_ int }

func (tp *TestP)SayHello() { tp.id_ = 1 }

func main() {

G_Test = TestS{}    //OK

G_Test = &TestS{}    //OK

G_Test = TestP{}    //compile error:cannot use TestP literal (type TestP) as type Itest in assignment:
                //TestP does not implement Itest (SayHello method has pointer receiver)
G_Test = &TestP{}    //OK

}

代码如上,TestS 和 TestP 都实现了接口 Itest,TestS 方法接收者是本身, TestP 方法接收者是其指针,然后为什么会报这种错误? 为什么当接收者不是指针的时候可以结构体本身和指针都能赋值给接口,而接收者是指针的时候就不行? 是否和隐式转换有关? 观察很多源码包(如bytes.Buffer,bytes.NewBuffer()返回的指针)都是写成接收者是指针,然后New结构体的方法返回的是指针。这样写的好处是什么?还是说是约定俗成?


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

952 次点击  
加入收藏 微博
4 回复  |  直到 2018-07-10 15:38:13
Prnyself
Prnyself · #1 · 7年之前

以值为接收者的方法被调用时,接收者既能为值又能为指针。 我之前记的这句话,但是不记得在哪本书里了 - - 所以func (ts TestS)SayHello() 在调用时候&TestS{}可以自动解析为*(&TestS{}) 也就满足了接口的定义 但是如果方法的接收者是指针的话,应该就不能自动解析了吧。所以接口赋值报错。 所以应该是为了写的时候方便,这是我自己的理解,希望能够帮到你

jdxj
jdxj · #2 · 7年之前
  • go语言圣经中有句话:在T类型的参数上调用一个*T的方法是合法的,只要这个参数是一个变量;编译器隐式的获取了它的地址。但这仅仅是一个语法糖:T类型的值不拥有所有*T指针的方法,那这样它就可能只实现更少的接口。
YerdGu
YerdGu · #3 · 7年之前
jdxjjdxj #2 回复

- go语言圣经中有句话:`在T类型的参数上调用一个*T的方法是合法的,只要这个参数是一个变量;编译器隐式的获取了它的地址。但这仅仅是一个语法糖:T类型的值不拥有所有*T指针的方法,那这样它就可能只实现更少的接口。`

啊哈,有点绕

YerdGu
YerdGu · #4 · 7年之前
PrnyselfPrnyself #1 回复

以值为接收者的方法被调用时,接收者既能为值又能为指针。 我之前记的这句话,但是不记得在哪本书里了 - - 所以func (ts TestS)SayHello() 在调用时候&TestS{}可以自动解析为*(&TestS{}) 也就满足了接口的定义 但是如果方法的接收者是指针的话,应该就不能自动解析了吧。所以接口赋值报错。 所以应该是为了写的时候方便,这是我自己的理解,希望能够帮到你

嗯,昨天问大佬也是这么解释的,thx

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传