即使使用指向类型的指针来更新它,我的对象也不会更新
我将一些Individual
对象存储在切片中。在将其附加到切片之前,我先打印Individual
对象的名称。
将其存储在切片中之后,我将其检索为指针,并希望将名称更改为"Peter"
,但是更改仍然有效,因为它仍然可以打印"Steve"
。为什么?
type Individual interface { GetName() *string
SetName(name string)
}
type Person struct {
name string
}
// Implement functions of the Individual interface
func (p Person) GetName() *string {
return &p.name
}
func (p Person) SetName(newName string) {
name := p.GetName();
*name = newName
}
var individuals []Individual
func main() {
person := Person{name: "Steve"}
fmt.Println(person)
individuals = append(individuals, person) // append Person to slice
p1 := individuals[0] // Retrieve the only Person from slice
p1.SetName("Peter") // Change name
fmt.Println(p1) // Should print "Peter", but prints "Steve"
fmt.Println(person) // Should print "Peter", but prints "Steve"
}
回答:
每当方法想要修改接收者时, ;该方法必须具有指针接收器。
如果方法具有非指针接收者,则在调用该方法时将创建并传递一个副本。从那时起,无论您对接收器做什么,都只能修改副本,而不能修改原始副本。
因此,在您的示例中:
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
}
这就是全部。
以上是 即使使用指向类型的指针来更新它,我的对象也不会更新 的全部内容, 来源链接: utcz.com/qa/397450.html