猿问

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

在下面的代码中,我展示了我认为在 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.someobj.printTest() //fine because I'm using the composed obj

    obj1Composed.printTest() //not fine - printTest is NOT promoted


芜湖不芜
浏览 135回答 3
3回答

慕侠2389804

值得仔细阅读有关嵌入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)时,这会变得更加有用。

精慕HU

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

慕容708150

在您的示例中,我还想针对第一种情况介绍一点。如果obj1Inherited和obj2具有相同名称的方法,则该方法调用(来自obj1Inherited实例)将始终执行obj1Inherited方法。要调用obj2方法,您可以使用不推广的其他方法
随时随地看视频慕课网APP

相关分类

Go
我要回答