每当方法想要修改接收者时, 它都必须是指向该值的指针 ;该方法必须具有指针接收器。
如果方法具有非指针接收者,则在调用该方法时将创建并传递一个副本。从那时起,无论您对接收器做什么,都只能修改副本,而不能修改原始副本。
因此,在您的示例中:
func (p Person) SetName(newName string) { name := p.GetName(); *name = newName}当
SetName()被调用时,一份拷贝的
Person。在内部,
SetName()您可以获取要修改
name的 副本 字段的地址。
(实际上,是该 副本的副本 ,稍后会详细介绍…)
解决方案:使用指针接收器:
func (p *Person) SetName(newName string) { name := p.GetName(); *name = newName}从这一点开始,仅
*Person实现
Individual,因此在添加时使用指针:
individuals = append(individuals, &person)
这很棘手,因为在此之后它将不再起作用。这是为什么?
这是因为
Person.GetName()仍然具有非指针接收器:
func (p Person) GetName() *string { return &p.name}因此,当
GetName()从中调用时
SetName(),将再次创建一个副本,
GetName()并将返回
name该 副本
字段的地址,并且
SetName()仅修改为call创建的副本
GetName()。
因此,要使所有工作正常进行,还必须将指针接收器用于
GetName():
func (p *Person) GetName() *string { return &p.name}现在它可以工作了,输出(在Go Playground上尝试):
{Steve}&{Peter}{Peter}但要知道,最简单和推荐的方法很简单:
func (p *Person) SetName(newName string) { p.name = newName}这就是全部。



