你为什么要在golang中使用组合?

时间:2016-04-18 21:22:52

标签: go

在下面的代码中,我展示了我认为在golang中嵌入(方法得到提升)和组合(不提升方法)之间的区别。

为什么你想在golang中使用合成?

type obj1Inherited struct {
    obj2
}

type obj1Composed struct {
    someobj obj2
}

type obj2 struct {
}

func (o obj2) printTest() {
    fmt.Println("obj2")
}

func main() {
    o := obj1Inherited{}
    o.printTest() //fine - printTest is promoted

    obj1Composed := obj1Composed{}
    obj1Composed.selector.printTest() //fine because I'm using the composed obj
    obj1Composed.printTest() //not fine - printTest is NOT promoted

4 个答案:

答案 0 :(得分:5)

值得仔细阅读有关嵌入Effective Go的内容。

一个常见的例子是使用带有互斥锁的结构/地图。

type SafeStruct struct {
    SomeField string 
    *sync.Mutex
}

输入

要容易得多
safe := SafeStruct{SomeField: "init value"}

safe.Lock()
defer safe.Unlock()
safe.SomeField = "new value"

比必须编写适当的包装函数(重复性)或具有

的断言
safe.mutex.Unlock()

当你对互斥字段做的唯一事情就是访问方法(在这种情况下为Lock()Unlock()

当您尝试在嵌入字段上使用多个函数(实现io.ReadWriter之类的接口)时,这会变得更有帮助。

答案 1 :(得分:0)

在您的示例中,我想介绍第一种情况。 如果obj1Inheritedobj2具有相同的名称方法,则该方法调用(来自obj1Inherited实例)将始终执行obj1Inherited方法。

要调用obj2方法,您可以使用另一种不升级的方法

答案 2 :(得分:0)

我将尝试回答原始问题 - 有时人们使用“组合”而不是嵌入来隐藏嵌入结构的功能。不是一个很好的用例 - 但人们有时更喜欢它。

type Obj1composed struct {
  notExportedObj1 obj1
}

func NewObj1Composed(someParam Params) Obj1composed {
...
}

func (o Obj1Composed) Print() {
  // Some heavy calculations here. Make Dozens of API calls
  // print some data
}

答案 3 :(得分:0)

在 Golang 中,有 3 种类型的 embed

  • 结构体嵌入结构体
  • 界面嵌入界面
  • 接口嵌入结构

详细可以参考这个帖子:https://eli.thegreenplace.net/2020/embedding-in-go-part-1-structs-in-structs/