【问题标题】:Struct inheritance in factory pattern工厂模式中的结构继承
【发布时间】:2020-11-22 15:44:22
【问题描述】:

我需要为一些结构创建继承者:

// Not interface, pure struct
type Base struct {
  A int
  B string
}

type Child struct {
  Base
  C bool
}

func (c *Child) SomeLoop() {
  for {
    // business logic
  }
}

创建子实例并从工厂返回

func maker() *Base {
  child := &Child {
    Base {
      A: 1
      B: "2"
    },
    C: false,
  }
  go child.Some()
  return child
}

使用字段 A 和 B 的基本结构从工厂制作的对象

o := maker()
fmt.Println(o.A, o.B) 

但我无法从 maker 函数返回 child 作为 base。这种模式如何实现?

【问题讨论】:

  • Go 中没有继承。完全没有。
  • 您不能将*Child 作为*Base 返回,因为它们是不同的类型。这么多应该很清楚。您要达到的实际目标是什么?可能有更好的方法。
  • 您似乎正在将其他语言生态系统的术语应用于 Go。 Go 本身就是一种独特的语言。因此,请告诉我们您想要实现什么样的行为 - 有一种 Go 方法可以做到这一点。
  • 我想从少数织物创建对象并存储在切片中 objects := []Base{ makeChild1(), // Child1 的织物 makeCHilds2(), // Child2 的织物 makeChild3 (), // Child3 的结构 } for _, o := range objects { fmt.Println(oA, oB) } 基本结构是外部的。我无法从外部包修改 Base 结构。
  • 当你说面料时,我很确定你的意思是factory,对吗?

标签: go inheritance factory


【解决方案1】:

Golang 没有继承,只有嵌入。您不能将 childmaker() 返回为 *Base。但是,您可以返回&child.Base(在过程中的返回值中丢失了指向child 的链接)。

最接近您想要的方法是为Base 定义一个interface{},并使用“能力”(函数)返回AB 的值:

type BaseInterface interface { // Don't actually name it like this
    // You would usually omit the "Get", but then
    // we'd get a name conflict with the fields later.
    // This may be avoided by making them lowercase, i.e. private.
    GetA() int
    GetB() string
}

然后,你可以为*Child实现这个:

// Note how this implements BaseInterface for Child and *Child alike.

func (child *Child) GetA() int {
    return child.A
}

func (child *Child) GetB() string {
    return child.B
}

然后,您可以将其返回为BaseInterface,如果需要,稍后进行类型断言以获得*Child 的原始类型:

returnedValue.(*Child) // Yes, this really is what the syntax looks like.

这有时是必要的,并且已被 Rob Pike(Golang 的发起者之一)承认是他们在 a talk at dotGo 2015 期间不引以为豪的语言方面之一。要点是不要试图在代码中引入语言旨在避免的复杂性。

【讨论】:

    猜你喜欢
    • 2020-10-25
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    相关资源
    最近更新 更多