在下面的代码中,我展示了我认为在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
答案 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)
在您的示例中,我想介绍第一种情况。
如果obj1Inherited
和obj2
具有相同的名称方法,则该方法调用(来自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/