douxianxing5712 2018-07-06 17:02
浏览 73
已采纳

包装的结构引用

I am little consfused about value type struct wrapped by pointer type struct.

Example:

package main

import (
    "fmt"
)

type A struct {
  id int
  B
}

func (a *A) setId(val int) {
  a.id = val
}

type B struct {
  name string
}

func (b B) setNameViaValue(val string) {
  b.name = val
}

func (b *B) setNameViaPointer(val string) {
  b.name = val
}

func main() {
    a := new(A)
    a.setId(1)
    a.setNameViaValue("valuename")
    fmt.Println(a)
    a.setNameViaPointer("pointername")
    fmt.Println(a)
}

I would expect that referencing through pointer type A struct(which addresses concrete memory) that wraps B value type struct will set inner value no matter what kind of refence to B is used (B/*B). This is also related to type definition. Can anyone also explain what is different when I define it like this? Is there any usecase scenario?

type A struct {
  id int
  *B
}
  • 写回答

1条回答 默认 最新

  • dongque6377 2018-07-06 17:10
    关注

    Why doesn't setNameViaValue end up setting the name

    If you declare a method with a value (non-pointer) receiver, then that method cannot "modify" the receiver cause it will actually receive a copy.

    That's why the "name" is not set as you expected with the setNameViaValue method.

    If you want to be able to set the name of B in that way, only setNameViaPointer is an option.

    You can read more about the differences between method and value receivers here:

    https://tour.golang.org/methods/8

    Why can you actually invoke the inner struct methods on the outer struct

    That's because you "embedded" the inner struct in the outer one.

    When you include a struct type name without giving it a field name, then all of the "inner" struct methods and fields are "promoted" to the outer one.

    That means you can call a.setNameViaValue and it will be equivalent to doing a.B.setNameViaValue.

    Is there any difference if I embedded as a pointer

    If you define A this way:

    type A struct {
      id int
      *B
    }
    

    Then:

    • The "setNameViaValue" will still not work (that's only related to the method being defined over a value instead of a pointer receiver, it has nothing to do with how A references B).

    • You will need to initialize B explicitly when creating an A object, otherwise *B will end up being nil. (if you reference it as a value, it will be initialized as an empty B)

    • You can change what *B points to later on (if it was a value, then it will always reference the same "value")

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程