请教类型T与*T的方法集的问题

用Go写面向对象的程序,按照文档上说(文档链接),类型T的成员方法是所有接收者为T的方法。而类型*T的方法除了包括接收者为*T的方法外,还包括所有接收者为T的方法。

我的理解是:

func (T) Hello() {
}

func (*T) Hello2() {
}

var t T
var pt *T = new(T)

那么可以t.Hello(),可以pt.Hello(),可以pt.Hello2(),但不能t.Hello2()。 可是测试一下不是这么回事啊,四个调用都可以。请问该怎么理解文档中这句话呢?

共 9 个回复


jimmykuu

As with selectors, a reference to a non-interface method with a value receiver using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv.

As with method calls, a reference to a non-interface method with a pointer receiver using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp.

http://godoc.golangtc.com/ref/spec#Method_values

# 0

bigbear

应该是说, 如果是直接申明的变量, 四种调用都是可以的. 如果t是通过一个方法返回的值类型, 就不能调用指针接收者的方法了.

func New_T( ) T

New_T( ).Hello2( ) 就不可以.

# 1

snake117

@bigbear 这是左右值的问题。对右值不能取地址,因此编译器无法进行自动适配。而左值则可以进行自动适配,所以值和指针可以互相调用对方的方法,当然实际上还是不同的,交叉调用时实际上进行了拷贝。类似的,如果是接口来调用方法,编译器也不会进行自动适配。

# 2

Anti_Magic

谢谢大家的回答,还是不太明白,是不是说T和*T的方法集肯定是一样的呢?

@jimmykuu 老大,“non-interface method”什么意思?接口的方法还用指定接收者么?另外本站未来会不会有@的功能呀。

# 3

gman

思考了半天 看了看 文档 感觉楼主的理解是对的,只是t.Hello2()的调用被go当成(&t).hello()这样执行了,所以hello2不在t的集合里。

不知道这样理解对不对。

# 4

ggaaooppeenngg

他那指的是接口,他说的方法集是接口的方法集,跟你给的例子没关系.

# 5

16779242

jimmykuu的回答已经很清楚了。

楼主理解的是interface{}的规则,而非一般规则。

对于一般方法而言,T *T调用是通用的。

但对于interface{}类型的方法调用,就是楼主所理解的那样子.

# 6

andypeker

@jimmykuu

你说的 “a non-interface method”, 怎么理解?

# 7

andypeker

@16779242

interface{}的规则 与 一般规则, 是什么区别?

# 8