从另一个包导入结构时的私有嵌入结构

问题描述 投票:0回答:3

我有一个项目依赖于从另一个包导入的结构,我将其称为

TheirEntity

在下面的示例中,我(咳咳)将

TheirEntity
嵌入到
MyEntity
中,这是
TheirEntity
的扩展,并增加了功能。

但是,我不想在

TheirEntity
结构中导出
MyEntity
,因为我希望消费者不要直接访问
TheirEntity

我知道 Go 嵌入与经典 OOP 中的继承不同,所以也许这不是正确的方法,但是是否可以将嵌入结构指定为“私有”,即使它们是从另一个包导入的?如何以更惯用的方式实现同样的事情?

// TheirEntity contains functionality I would like to use...

type TheirEntity struct {
    name string
}

func (t TheirEntity) PrintName() {
    fmt.Println(t.name)
}

func NewTheirEntity(name string) *TheirEntity {
    return &TheirEntity{name: name}
}

// ... by embedding in MyEntity

type MyEntity struct {
    *TheirEntity // However, I don't want to expose 
                 // TheirEntity directly. How to embed this
                 // without exporting and not changing this
                 // to a named field?

    color        string
}

func (m MyEntity) PrintFavoriteColor() {
    fmt.Println(m.color)
}

func NewMyEntity(name string, color string) *MyEntity {
    return &MyEntity{
        TheirEntity: NewTheirEntity(name),
        color:       color,
    }
}
go encapsulation embedding
3个回答
15
投票

自从提出问题以来,Go 1.9 看到了语言中添加了 类型别名。通过非常规地使用类型别名,您实际上可以鱼与熊掌兼得!

首先,为您希望嵌入到结构中的第三方类型声明一个未导出的别名:

type theirEntity = TheirEntity

然后,只需嵌入该别名而不是原始类型:

type MyEntity struct {
    *theirEntity
    color string
}

(游乐场)


5
投票

像这样:

type MyEntity struct {
    *privateTheirEntity
}

type privateTheirEntity struct {
    *TheirEntity
}

2
投票

[I]是否可以将嵌入结构指定为“私有”,即使它们是从另一个包导入的?

没有。

如何以更惯用的方式实现同样的事情?

通过不嵌入但使其成为未导出的命名字段。

© www.soinside.com 2019 - 2024. All rights reserved.