duanla8800 2019-05-16 17:11
浏览 45

函数接收器的地址因方法而异

I have the following code. https://play.golang.org/p/YAa6cgtA3Vo

The address of the receiver pointer varies between method calls. This is perplexing. Can anyone explain why this is the case? Do I need to pass a pointer to a receiver as an argument in order to maintain the same address?

type myStruct struct {
    //struct content is irrelevant
}

func (ptrToStruct *myStruct) returnAddress() **myStruct {
    return &ptrToStruct
}

func (ptrToStruct *myStruct) method1() {
    addressOfPtr := ptrToStruct.returnAddress()
    fmt.Println(&ptrToStruct)
    fmt.Println(addressOfPtr)
    if &ptrToStruct != addressOfPtr {
        fmt.Println("Different addresses!")
    }
}

EDIT:

What I want is the address of ptrToStruct and not its value. I know that I could just get it in method1() by typing addressOfPtr = &ptrToStruct but in my use case I have some logic happening in the returnAddress() method and I need it to come from there.

  • 写回答

1条回答 默认 最新

  • douping3860 2019-05-16 17:23
    关注

    That's simple: when you have var ms myStruct somewhere, calling ms.returnAddress() would pass the address of the ms variable to returnAddress, and that address would always be the same (this is easily verifyable — try it itself).

    Now consider that the ptrToStruct in the returnAddress definition is just a special argument to be passed to that method, and it has a concrete type — *myStruct.

    This type internally is just an integer — large enough to store an address of any memory location on your platform/OS combination.

    Now consider that when the call ms.returnAddress() is performed, the address of the ms variable is taken and written to the ptrToStruct argument passed to returnAddress. And that argument is also a variable — with the lifetime equal to the duration of the function call, and visible only in that function's body.

    This variable is automatically created on the call stack by the code which prepares the function call. (And the same happens to all the other method arguments.)

    So, when you take the address of ptrToStuct, you take the address of a variable appeared at some location on the call stack which will be gone once the method returns.

    Now consider that:

    • goroutine stacks in Go are growable (and hence may be relocated in memory when grown);
    • a method may be called from different goroutines (each has its own stack);
    • even if the method is called from the same goroutine multiple times, it may be called from different places in the code path executed by that goroutine.

    All of the above may lead to the address of ptrToStruct variable being essentially random from call to call.

    What you (probably) actually want is just returning the value of ptrToStruct as is, not its address.

    If you feel like not really getting into how ptrToStruct springs into existence and vanishes, consider starting with this.

    评论

报告相同问题?

悬赏问题

  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化