方法接收器与指针之间的区别与否

时间:2014-01-10 22:26:20

标签: methods go

为什么我不能将PrintValue()定义为指针接收器(* One)才能打印“hello”?

package main
import "fmt"


type One struct{
    a string
}
func (o *One)AssignValue(){
    o.a = "hello"
}
func (o One)PrintValue(){
    fmt.Println(o.a)
}

func main() {
    one := One{}
    one.AssignValue()
    one.PrintValue()
}

1 个答案:

答案 0 :(得分:0)

因为one已经是One类型。实例化语法

t := One{}

在表格

时创建One类型的
p := &One{}

创建一个指向One类型值的指针。

这意味着在调用t.PrintValue时无需执行任何操作,因为接收方类型(One)已经与tOne的类型相同)。

当调用p.PrintValue时,编译器会自动将可寻址变量转换为其指针形式,因为接收器类型(One)不等于p的类型(*One )。所以表达式

p.PrintValue()

转换为

(*p).PrintValue()

调用t.AssignValue时还需要进行转换,因为此方法有一个指针接收器但我们提供了一个值。这也是编译器在可能的情况下自动完成的。

来自the spec on calls

  

如果方法集x(类型)x包含m并且参数列表可以分配给m的参数列表,则方法调用x.m()有效。 如果x是可寻址的且& x的方法集包含m,则x.m()是(& x).m()

的缩写

这意味着表达式

t.AssignValue()

转换为

(&t).AssignValue()

请注意,这并非总是可行。例如,从函数返回值时:

func NewOne(s string) One { return One{s} }

NewOne("foo").AssignValue() // Not possible

x := NewOne("foo")
x.AssignValue() // Possible, automatically converted