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

Private embedded struct when importing a struct from another package

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

在下面的示例中,我(咳咳)将 TheirEntity 嵌入到 MyEntity 中,它是 TheirEntity 的扩展,具有附加功能。

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

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

// 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,
    }
}

[I]s it possible to specify embedded structs as "private", even if they are imported from another package?

没有

How might one achieve the same thing in a more idiomatic fashion?

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

像这样:

type MyEntity struct {
    *privateTheirEntity
}

type privateTheirEntity struct {
    *TheirEntity
}

自问这个问题以来,Go 在 2017 年看到了 type aliases to the language with the 1.9 release 的添加。事实证明,通过非常规使用类型别名,您也可以吃蛋糕!

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

type theirEntity = TheirEntity

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

type MyEntity struct {
    *theirEntity
    color string
}

(Playground)