duanmo6937 2017-08-27 20:46
浏览 44
已采纳

使用父结构的方法更改嵌入式结构的属性

I have to periodically call a method of a parent struct but when called, it must update extended properties unique to the embedded struct (in my case the structs have different id data types).

The only solution I could think of was to override the a method of the parent struct so that, when the periodic method is called again, it uses the method of the embedded struct instead of the parent's original.

The code looks as follows:

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())
}

While the above code does work, I have two concerns when the parent struct Fruit needs eg. 10 additional properties with their required SetXXX(*XXX) methods:

  1. Then all the embedded structs has to be updated to reflect the new parent struct methods. Which seems like a lot of necessary coding per property.

  2. Some of these embedded structs will not need all of the property methods, leaving a few nil. A good example being not all fruit grow on trees. Leaving property at comment #2 useless for Strawberry.

Are both these concerns valid and is there a way I can avoid them?

P.S. The application requires a lot of operational throughput so ideally the code should be type safe and optimal without the use of reflection and the overuse of type assertion (can't make every property interface{}).

  • 写回答

1条回答 默认 最新

  • duanjing7651 2017-08-28 06:02
    关注

    Are both these concerns valid and is there a way I can avoid them?

    No and yes.

    Just write idiomatic GO and do not try to write traditional OO in Go. E.g. Setters and Getters are not common in Go. And stop thinking of embedding as a parent/child relation.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 chaquopy python 安卓
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 有没有帮写代码做实验仿真的
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥30 vmware exsi重置后登不上
  • ¥15 易盾点选的cb参数怎么解啊
  • ¥15 MATLAB运行显示错误,如何解决?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题