【问题标题】:Embedding when to use pointer嵌入何时使用指针
【发布时间】:2015-01-01 19:19:33
【问题描述】:

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

例如

type Job struct {
    Command string
    *log.Logger
}

type Job struct {
    Command string
    log.Logger
}

【问题讨论】:

    标签: go embedding


    【解决方案1】:

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

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

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

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


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

    • 这样做的第一个好处是,您可以依赖使用 NewX 惯用语返回结构体指针的函数进行初始化。
    • 第二个优点是您可以嵌入一个类型的所有功能,而无需知道它何时被实例化
      指向 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中所述:

    你不能有指向指针和指向接口匿名字段的指针的原因是这些类型没有方法。
    匿名字段的全部意义在于方法得到提升

    我已经解释了为什么接口没有方法:很多人错误且不必要地使用了指向接口的指针,并且没有任何已知的有效用途,因此更改了语言以通过制作指针来积极阻止这种用法to 接口没有方法。

    【讨论】:

    • as a pointer to a non-interface type name *T 这是什么意思?
    • The whole point of anonymous fields is that methods get promoted. 提升是什么意思?
    • @zero_coding 表示嵌入类型的方法可以通过父类型访问/可见。
    • @zero_coding 例如*log.Logger 是一个指向非接口类型的指针:它可以嵌入。
    猜你喜欢
    • 2015-04-14
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    相关资源
    最近更新 更多