我的目标是不更新,即使我用指针类型进行更新我的目标是不更新,即使我用指针类型进行更新(My obje

2019-05-12 06:18发布

我有些存放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"
}

Answer 1:

每当一个方法想要修改接收器, 它必须是一个指针值 ; 该方法必须有一个指针接收器。

如果一个方法具有非指针接收器,副本将被制成,当调用该方法通过。 从这一点来说,无论你与接收器做什么,你只能修改副本,而不是原来的。

因此,在你的例子:

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()仅修改调用创建副本GetName()

因此,为了使所有的工作,你也可以选择使用指针接收器GetName()

func (p *Person) GetName() *string {
    return &p.name
}

现在,它的工作,输出(尝试在转到操场 ):

{Steve}
&{Peter}
{Peter}

但要知道,最简单,最推荐的方法很简单:

func (p *Person) SetName(newName string) {
    p.name = newName
}

这一切都需要。



Answer 2:

两件事情来解决这个问题:

  • 你需要的方法通过“指针”的方法连接,否则名称只在方法内改变。
  • 您需要使用指针实际的Person的变量,因为它们需要实现一个接口
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)  {
    p.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)          // Prints "Steve"
    fmt.Println(person)      // Prints "Steve"
}

例如在去游乐场 。



Answer 3:

见https://play.golang.org/p/eg8oYDV6Xx p1和p2都已经解决了,你不需要他们的地址(地址的地址),只需打印p1和p2 -他们将是一样的,你可以看到。



文章来源: My object is not updated even if I use the pointer to a type to update it