嵌入何时使用指针

zer*_*ing 3 embedding go

当我想在另一个struct中嵌入一个struct时,我应该使用指针或值吗?

例如

type Job struct {
    Command string
    *log.Logger
}
Run Code Online (Sandbox Code Playgroud)

要么

type Job struct {
    Command string
    log.Logger
}
Run Code Online (Sandbox Code Playgroud)

Von*_*onC 8

您可以使用其中一种:对于struct类型,规范提到:

使用类型但没有显式字段名称声明的字段是匿名字段,也称为嵌入字段或在结构中嵌入类型.

必须将嵌入类型指定为类型名称T或指向非接口类型名称的指针*T,并且T它本身可能不是指针类型.

既然log.Logger不是一个接口,可以使用类型或指针为匿名字段的类型Logger.


Eric Urban()的文章" Embedding in Go " 调用嵌入指针" 嵌入指针 ":hydrogen18

  • 这样做的第一个好处是你可以依赖使用NewXidiom的函数返回struct by-pointer来进行初始化.
  • 第二个优点是您可以嵌入类型的所有功能,而无需知道何时实例化.
    嵌入式指针指向a Bitmap与Go中的任何其他指针没有什么不同,因此可以多次指定它.
    通过执行此操作,您可以更改在运行时动态扩展的实例.

例如,用:

type Bitmap struct{
    data [4][5]bool
}

type Renderer struct{
    *Bitmap //Embed by pointer
    on uint8
    off uint8
}
Run Code Online (Sandbox Code Playgroud)

Renderer类型嵌入了一个Bitmap指针.

单个实例Bitmap可以充当许多Renderer实例的嵌入式实例:

var renderA,renderB Renderer
renderA.on = 'X'
renderA.off = 'O'
renderB.on = '@'
renderB.off = '.'

var pic Bitmap
pic.data[0][6] = true
pic.data[0][7] = true
pic.data[1][8] = true
pic.data[2][9] = true
pic.data[3][10] = true

renderA.Bitmap = &pic
renderB.Bitmap = &pic

renderA.render()
renderB.render()
Run Code Online (Sandbox Code Playgroud)

Bitmap与两个不同的渲染器共享相同的实例.
每个渲染器都有自己的一组字符,允许打印两个位图表示.
这是输出的样子:

OXXO
OXOO
OXOO
OXOO
.@@.
.@..
.@..
.@..
Run Code Online (Sandbox Code Playgroud)

此示例演示了Flyweight模式.
尽管在该示例中对于存储器消耗无关紧要,但是具有共享单个底层数据结构的数千个实例在减少系统的存储器消耗方面可能是非常重要的.


正如这个帖子中提到的:

你不能指向指向接口匿名字段的指针和指针的原因是这些类型没有方法.
匿名字段的重点是方法得到提升.

我已经解释了为什么接口没有方法:很多人使用指针错误地和不必要地使用指针,并且没有任何已知的有效用途,所以语言被改为主动阻止这种用法通过指向接口有没办法.