简体   繁体   English

为什么struct引用的内存地址会发生变化?

[英]Why does the memory address of a struct reference change?

I have a struct and a method that's working on the structs reference. 我有一个结构和方法正在处理结构参考。 The pointer address is changing every time I call the method. 每次调用方法时指针地址都在变化。 Why is it like that? 为什么会那样?

Code

package main

import "k8s.io/contrib/compare/Godeps/_workspace/src/github.com/emicklei/go-restful/log"

type Whatever struct{
    Name string
}

func (whatever *Whatever) GetNameByReference() (string) {
log.Printf("Whatever.GetNameByReference() memory address: %v", &whatever)

    return whatever.Name
}

func evaluateMemoryAddressWhenNotWritingAnything()  {
    whatever := Whatever{}

    whatever.GetNameByReference()
    whatever.GetNameByReference()
    whatever.GetNameByReference()
}

func main() {
    evaluateMemoryAddressWhenNotWritingAnything()
}

Output: 输出:

log.go:30: Whatever.GetNameByReference() memory address: 0xc420034020
log.go:30: Whatever.GetNameByReference() memory address: 0xc420034030
log.go:30: Whatever.GetNameByReference() memory address: 0xc420034038

Never think and never talk about references. 永远不要思考,永远不要谈论参考。 Go has no notion of "reference", everything is a value. Go没有“参考”的概念,一切都是价值。 Some things are pointer values. 有些东西是指针值。 Your problem stems from thinking about *X as "a reference to an X" which it isn't: It is a value holding the memory address of an X (or nil). 你的问题源于将*X视为“对*X的引用”,它不是:它是一个保存X (或零)内存地址的值。

So in func (whatever *Whatever) the variable whatever is a pointer to a Whatever . 所以在func (whatever *Whatever)变量whatever是指向Whatever的指针。 The value of whatever is the memory address of the Whatever the pointer points to. 的价值whatever是内存地址Whatever指针指向。 You would like to print this memory address, ie the value of whatever . 您想打印此内存地址,即whatever值。

You do Printf("%v", &whatever) . 你做Printf("%v", &whatever) Remember: whatever is a variable (holding a memory address). 记住: whatever是变量(保存内存地址)。 So &whatever is the address of the variable itself: &whatever is of type **Whatever . 所以&whatever变量本身的地址是&whatever&whatever类型**Whatever What you find at the address &whatever is not the value you are interested in; 你找到的地址&whatever是你感兴趣的值; it is just the temporary variable used to store the address of the original Whatever . 它只是用于存储原始Whatever地址的临时变量。 Of course this temporary variable is not pinned in memory an may change freely. 当然,这个临时变量没有固定在内存中,可能会自由变化。

You should do Printf("%p", whatever) . 你应该做Printf("%p", whatever) The verb %p is for pointer values and whatever is a pointer and you are interested in its value, so print this value. 动词%p用于指针值, whatever指针是whatever并且您对其值感兴趣,因此请打印此值。

You are not displaying the address of the struct, you are displaying the address of the address (address of the pointer). 您没有显示结构的地址,您正在显示地址的地址(指针的地址)。 The pointer is passed as a parameter and thus new each time. 指针作为参数传递,因此每次都是新的。 Remove the & in log.Printf("Whatever.GetNameByReference() memory address: %v", &whatever) to get what you want (and use %p instead of %v). 删除&in log.Printf("Whatever.GetNameByReference() memory address: %v", &whatever)以获得所需内容(并使用%p而不是%v)。

Calling method 通话方式

func (whatever *Whatever) GetNameByReference() (string) {

is much the same as calling function providing receiver as first argument 与调用函数提供接收器作为第一个参数非常相似

func GetNameByReference(whatever *Whatever) (string) {

Go calling convention is to always pass arguments copy_by_value. Go调用约定总是传递参数copy_by_value。 So each time you call whatever.GetNameByReference() it receives fresh copy of whatever which itself holds same *Whatever address. 所以每次你调用whatever.GetNameByReference()它会收到whatever本身拥有相同*Whatever地址的新副本。 As already written doing 正如已经写好的那样

log.Printf("Whatever.GetNameByReference() memory address: %v", whatever) //instead of &whatever

will log the same whatever value which is address. 将记录同whatever值是地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM