一尘不染

嵌入何时使用指针

go

当我想将一个结构嵌入另一个结构中时,应该使用指针还是值?

例如

type Job struct {
    Command string
    *log.Logger
}

要么

type Job struct {
    Command string
    log.Logger
}

阅读 157

收藏
2020-07-02

共1个答案

一尘不染

您可以使用其中之一:对于struct type,规范中提到:

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

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

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


Eric
Urban(
的文章“
Embeding in Go
将嵌入指针称为“ embed by-pointer ”:hydrogen18


  • 这样做的第一个优点是,您可以依靠使用该NewX惯用语返回结构按指针的函数来进行初始化。
  • 第二个优点是, 您可以嵌入类型的所有功能,而无需知道何时实例化它
    指向a的嵌入式指针与BitmapGo中的任何其他指针没有什么不同,因此可以多次分配它。
    这样,您可以更改在运行时动态扩展的实例。

例如,使用:

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模式
尽管在此示例中与内存消耗无关紧要,但具有成千上万个实例共享单个基础数据结构对于减少系统的内存消耗可能非常重要。


本线程所述

之所以没有指针和指向接口匿名字段的指针,是因为这些类型没有方法。
匿名字段的全部要点是方法得到了推广

我已经解释了为什么接口没有方法:很多人错误地和不必要地使用了指向接口的指针,并且没有任何已知的有效用法,因此更改了语言,以通过使指向接口的指针具有没有办法。

2020-07-02