In golang, How can I override the embedded struct's method

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

In golang, How can I override the embedded struct's method

问题

这是你提供的代码的翻译结果:

package main

import "fmt"

func main() {
    t16()
}

type Base struct {
    val int
}

func (b *Base) Set(i int) {
    b.val = i
}

type Sub struct {
    Base
    changed bool
}

func (b *Sub) Set(i int) {
    b.val = i
    b.changed = true
}

func t16() {
    s := &Sub{}
    s.Base.Set(1)
    var b *Base = &s.Base
    fmt.Printf("%+v\n", b)
    fmt.Printf("%+v\n", s)
}

我希望在调用Base.Set时,能够标记更改,对于用户来说,他们不知道实际上使用的是Sub,所以我可以监视Base的行为。

func t16() {
    s := &Sub{}
    var b *Base = &s.Base
    b.Set(10)
    fmt.Printf("%+v\n", b)
    fmt.Printf("%+v\n", s)
}

请注意,这只是代码的翻译,我无法运行代码或提供关于代码功能的保证。

英文:

Code here

package main

import "fmt"

func main() {
	t16()
}

type Base struct {
	val int
}
func (b *Base)Set(i int) {
	b.val = i
}
type Sub struct {
	Base
	changed bool
}

func (b *Sub)Set(i int) {
	b.val = i
	b.changed = true
}
func t16() {
	s := &Sub{}
	s.Base.Set(1)
	var b *Base = &s.Base
	fmt.Printf("%+v\n", b)
	fmt.Printf("%+v\n", s)
}

I want to make Sub act as Base, but when I call Set, for Sub it will mark the changed.I know there is no polymorphism or proxy in golang, but is there any way to do this, and not effect the Base?

UPDATED

I hope when I call Base.Set it will mark the change, for user, they don't know they actually use the Sub, so I can monitor the Base behave.

func t16() {
	s := &Sub{}
	var b *Base = &s.Base
	b.Set(10)
	fmt.Printf("%+v\n", b)
	fmt.Printf("%+v\n", s)
}

答案1

得分: 7

通过将Sub嵌入Base,它自动拥有了Base的所有字段和函数,这意味着你可以直接调用s.val,并且你本来可以调用s.Set来调用基类函数,但是由于Sub实现了自己的Set方法,它隐藏了基类的方法。

当你在示例中调用s.Base.Set()时,你绕过了Sub.Set(),直接调用了Base.Set()

在你的情况下,修复方法很简单,只需调用s.Set()而不是s.Base.Set()

以下代码对我有效:

func (b *Sub) Set(i int) {
    b.Base.Set(i)
    b.changed = true
}
func t16() {
    s := &Sub{}
    s.Set(1)
    var b *Base = &s.Base
    fmt.Printf("%+v\n", b)
    fmt.Printf("%+v\n", s)
}

Play链接

请注意,Sub.Set()也可以调用嵌入结构体的方法,这在某种程度上类似于其他面向对象语言提供的super()类型继承。

英文:

By having Sub embed Base it automatically has all of Base's fields and functions made available as top level members of Sub. This means you can directly call s.val, and you would be able to call s.Set to invoke the base function except for the fact that Sub implemented its own Set method which hides the Base one.

When you call s.Base.Set() in your example you are bypassing Sub.Set() and directly calling Base.Set().

To fix it in your case is as simple as calling s.Set() instead of s.Base.Set().

This works for me:

func (b *Sub)Set(i int) {
	b.Base.Set(i)
	b.changed = true
}
func t16() {
	s := &Sub{}
	s.Set(1)
	var b *Base = &s.Base
	fmt.Printf("%+v\n", b)
	fmt.Printf("%+v\n", s)
}

Play link

Notice that Sub.Set() can invoke the embedded structs method as well, which feels a lot like the super() type inheritance that other oo languages provide.

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

发表评论

匿名网友

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

确定