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

huangapple go评论65阅读模式
英文:

Private embedded struct when importing a struct from another package

问题

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

在下面的示例中,我将TheirEntity嵌入到MyEntity中,MyEntityTheirEntity的扩展,具有额外的功能。

然而,我不想在MyEntity结构体中导出TheirEntity,因为我希望消费者不能直接访问TheirEntity

我知道Go语言中的嵌入不同于经典面向对象编程中的继承,所以也许这不是正确的方法,但是是否可能将嵌入的结构体指定为“私有”,即使它们是从另一个包中导入的?如何以更符合惯例的方式实现相同的效果?

// TheirEntity 包含我想要使用的功能...

type TheirEntity struct {
	name string
}

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

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

// ...通过嵌入在 MyEntity 中使用

type MyEntity struct {
	*TheirEntity // 但是,我不想直接暴露 TheirEntity。如何嵌入它而不导出,并且不将其更改为命名字段?

	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 have a project which relies on a struct imported from another package, which I will call TheirEntity.

In the example below, I (ahem) embed TheirEntity in MyEntity, which is an extension of TheirEntity, with added functionality.

However, I don't want to export TheirEntity in the MyEntity structure, as I would rather the consumer not access TheirEntity directly.

I know that Go embedding is not the same as inheritance in classical OOP, so maybe this is not the correct approach, but is 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?

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

答案1

得分: 12

自从问题被提出以来,Go语言在2017年的1.9版本中引入了类型别名(type aliases)的功能。通过非常规的类型别名使用方式,你可以同时满足需求。

首先,为你想要嵌入在结构体中的第三方类型声明一个未导出的别名:

type theirEntity = TheirEntity

然后,简单地将该别名嵌入到结构体中,而不是原始类型:

type MyEntity struct {
	*theirEntity
	color string
}

Playground

英文:

Since the question was asked, Go saw the addition of type aliases to the language with the 1.9 release in 2017. It turns out that, through an unconventional use of type aliases, you can have your cake and eat it too!

First, declare an unexported alias for the third-party type you wish to embed in your struct:

type theirEntity = TheirEntity

Then, simply embed that alias instead of the original type:

type MyEntity struct {
	*theirEntity
	color string
}

(Playground)

答案2

得分: 4

你好!以下是翻译好的内容:

> 是否可以将嵌入的结构体指定为“private”,即使它们来自另一个包?

不可以。

> 如何以更符合惯用方式的方式实现相同的效果?

通过不嵌入,而是将其作为未导出的命名字段。

英文:

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

No.

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

By not-embedding but making it a unexported named field.

答案3

得分: 4

像这样:

type MyEntity struct {
    *privateTheirEntity
}

type privateTheirEntity struct {
    *TheirEntity
}
英文:

Like this:

type MyEntity struct {
    *privateTheirEntity
}

type privateTheirEntity struct {
    *TheirEntity
}

huangapple
  • 本文由 发表于 2015年11月25日 12:50:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/33908672.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定