[英]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.