英文:
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)
}
请注意,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)
}
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论