为什么SetAge()方法不能正确设置年龄?

huangapple go评论74阅读模式
英文:

Why does the SetAge() method not set the age correctly?

问题

我正在尝试使用Go语言和接口以及结构体继承进行实验。

我创建了一组结构体,想法是可以将通用的方法和值保存在一个核心结构体中,然后通过继承这个结构体并添加适当的额外值:

type NamedThing interface {
    GetName() string
    GetAge()  int
    SetAge(age int)
}

type BaseThing struct {
   name string
   age  int
}

func (t BaseThing) GetName() string {
   return t.name
}

func (t BaseThing) GetAge() int {
   return t.age
}

func (t BaseThing) SetAge(age int) {
   t.age = age
}

type Person struct {
   BaseThing
}

func main() {
    p := Person{}
    p.BaseThing.name = "fred"
    p.BaseThing.age = 21
    fmt.Println(p)
    p.SetAge(35)
    fmt.Println(p)
}

你也可以在Go Playground上找到这段代码:

https://play.golang.org/p/OxzuaQkafj

然而,当我运行main方法时,年龄仍然保持为"21",并且没有被SetAge()方法更新。

我试图理解为什么会出现这种情况,以及我需要做什么才能使SetAge方法正常工作。

英文:

I'm experimenting with GoLang and interfaces and struct inheritence.

I've created a set of structures with the idea that I can keep common methods and values in a core structure an then just inherit this and add extra values as appropriate:

type NamedThing interface {
    GetName() string
    GetAge()  int
    SetAge(age int)
}

type BaseThing struct {
   name string
   age  int
}

func (t BaseThing) GetName() string {
   return t.name
}

func (t BaseThing) GetAge() int {
   return t.age
}

func (t BaseThing) SetAge(age int) {
   t.age = age
}

type Person struct {
   BaseThing
}

func main() {
	p := Person{}
	p.BaseThing.name = "fred"
	p.BaseThing.age = 21
	fmt.Println(p)
	p.SetAge(35)
	fmt.Println(p)
}

Which you can also find here in the go playground:

https://play.golang.org/p/OxzuaQkafj

However when I run the main method, the age remains as "21" and isn't updated by the SetAge() method.

I'm trying to understand why this is and what I'd need to do to make SetAge work correctly.

答案1

得分: 5

你的函数接收者是值类型,所以它们被复制到函数作用域中。为了影响函数之外的接收类型的生命周期,你的接收者应该是指向你的类型的指针。请参考下面的代码:

type NamedThing interface {
    GetName() string
    GetAge()  int
    SetAge(age int)
}

type BaseThing struct {
   name string
   age  int
}

func (t *BaseThing) GetName() string {
   return t.name
}

func (t *BaseThing) GetAge() int {
   return t.age
}

func (t *BaseThing) SetAge(age int) {
   t.age = age
}

type Person struct {
   BaseThing
}

func main() {
    p := Person{}
    p.BaseThing.name = "fred"
    p.BaseThing.age = 21
    fmt.Println(p)
    p.SetAge(35)
    fmt.Println(p)
}

这段代码定义了一个接口NamedThing和两个结构体BaseThingPersonBaseThing结构体包含了nameage字段,而Person结构体嵌入了BaseThing结构体。BaseThing结构体实现了NamedThing接口的方法GetName()GetAge()SetAge()。在main()函数中,我们创建了一个Person对象p,并通过p.BaseThing.namep.BaseThing.age来访问BaseThing结构体的字段。然后我们调用了p.SetAge(35)方法来修改p的年龄,并打印出p的值。

英文:

Your function receiver's are value types, so they are copied into your function scope. To affect your received type past the lifetime of the function your receiver should be a pointer to your type. See below.

type NamedThing interface {
    GetName() string
    GetAge()  int
    SetAge(age int)
}

type BaseThing struct {
   name string
   age  int
}

func (t *BaseThing) GetName() string {
   return t.name
}

func (t *BaseThing) GetAge() int {
   return t.age
}

func (t *BaseThing) SetAge(age int) {
   t.age = age
}

type Person struct {
   BaseThing
}

func main() {
    p := Person{}
    p.BaseThing.name = "fred"
    p.BaseThing.age = 21
    fmt.Println(p)
    p.SetAge(35)
    fmt.Println(p)
}

huangapple
  • 本文由 发表于 2016年12月4日 06:11:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/40953040.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定