嵌入何时使用指针

时间:2015-01-01 19:19:33

标签: go embedding

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

例如

type Job struct {
    Command string
    *log.Logger
}

type Job struct {
    Command string
    log.Logger
}

1 个答案:

答案 0 :(得分:5)

您可以使用其中一个:struct type,规范提及:

  

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

     

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

由于log.Logger 不是接口,您可以使用类型或指向匿名字段Logger类型的指针。


文章&#34; Embedding in Go &#34;来自Eric Urban (hydrogen18)来自嵌入指针&#34; 嵌入指针&#34;:

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

例如,用:

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

type Renderer struct{
    *Bitmap //Embed by pointer
    on uint8
    off uint8
}

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()
  

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

OXXO
OXOO
OXOO
OXOO
.@@.
.@..
.@..
.@..
  

此示例演示了Flyweight Pattern   虽然在这个例子中对内存消耗无关紧要,但是有数千个实例共享一个底层数据结构对于减少系统的内存消耗非常重要。


this thread中所述:

  

您无法指向指向匿名字段的指针和指针的原因是这些类型没有方法。
  匿名字段的重点是提升方法

     

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