使用其父级中的方法更改嵌入式结构的属性
问题描述:
我必须定期调用父级结构的方法,但调用时必须更新嵌入式结构唯一的扩展属性(在我的情况中,结构具有不同的id数据类型)。使用其父级中的方法更改嵌入式结构的属性
我能想到的唯一解决方案是重写父结构的方法,以便在再次调用周期性方法时,它使用嵌入结构的方法而不是父母的原始结构。
的代码如下:
package main
import (
"fmt"
)
type Fruit struct {
image *Image
tree *Tree
SetImage func(*Image)
SetTree func(*Tree) // #2 (always nil for Strawberry)
}
func NewFruit() *Fruit {
f := &Fruit{}
f.SetImage = f.setImage
f.SetTree = f.setTree
return f
}
func (f *Fruit) Image() *Image {
return f.image
}
func (f *Fruit) Tree() *Tree {
return f.tree
}
func (f *Fruit) setImage(i *Image) {
f.image = i
}
func (f *Fruit) setTree(t *Tree) {
f.tree = t
}
type Strawberry struct {
*Fruit
id int
}
func NewStrawberry(f *Fruit) *Strawberry {
strawberry := &Strawberry{Fruit: f}
return strawberry
}
func (s *Strawberry) SetID(i int) {
s.id = i
}
func (s *Strawberry) ID() int {
return s.id
}
func (s *Strawberry) setImage(i *Image) {
s.id = 6
s.image = i
}
type Kiwi struct {
*Fruit
id string
}
func NewKiwi(f *Fruit) *Kiwi {
kiwi := &Kiwi{Fruit: f}
return kiwi
}
func (k *Kiwi) SetID(i string) {
k.id = i
}
func (k *Kiwi) ID() string {
return k.id
}
func (k *Kiwi) setImage(i *Image) {
k.id = "abc"
k.image = i
}
func (k *Kiwi) setTree(t *Tree) {
k.tree = t
}
type Image struct {
path string
}
type Tree struct {
height int
}
func main() {
f := NewFruit()
f.SetImage(&Image{"kiwi1.jpg"})
/*s := NewStrawberry(f)
s.SetImage = s.setImage
fmt.Println(s, s.ID(), s.Image())
f.SetImage(&Image{"strawberry.jpg"})
fmt.Println(s, s.ID(), s.Image())*/
k := NewKiwi(f)
k.SetImage = k.setImage
k.SetTree = k.setTree
fmt.Println(k, k.ID(), k.Image())
f.SetImage(&Image{"kiwi2.jpg"})
f.SetTree(&Tree{2})
fmt.Println(k, k.ID(), k.Image(), k.Tree())
}
虽然上面的代码做的工作,我有两个顾虑时Fruit
需要如父结构。他们需要SetXXX(*XXX)
方法10个附加属性:
然后所有的嵌入式结构必须被更新,以反映新的父结构的方法。这似乎是每个属性的很多必要的编码。
其中一些嵌入式结构不需要所有的属性方法,只留下几个
nil
。一个很好的例子并不是所有的果实都生长在树上。在评论#2
离开财产Strawberry
没用。
这两个问题都有效,有没有办法避免它们?
P.S. 该应用程序需要大量的操作吞吐量,因此理想情况下代码应该是类型安全和最佳的,而不使用反射和过度使用类型断言(不能使每个属性interface{}
)。
答
这两个问题都是有效的,有没有办法避免它们?
没有,是的。
只要写出惯用的GO并且做不是尝试在Go中写传统的OO。例如。 Go中不常见Setter和Getter。并且不要想到嵌入作为父母/孩子的关系。
我不明白它如何写得不同(惯用的Go方式)。你能否提供一个解决我问题第一句中提到的问题的反例。 由于缺乏一个更好的单词,我使用了“父母”。 –
@FanusduToit你写了“所有的嵌入式结构必须更新以反映新的父结构方法”,这是错误的。结构嵌入促进方法。如果嵌入类型有一个方法,那么嵌入类型的方法集通过这种方法得到了增强(给出了一些技术细节)。只要摆脱这种无意义的Setters并阅读https://golang.org/ref/spec#Struct_types,重点关注方法集。 – Volker
你最近的评论比最初的答案要好得多。我现在明白了为什么我的'setters'是无用的,因为你实际上帮助我理解了为什么。谢谢! –