如何打印Go对象的指针值? 指针值是什么意思?

我只是围绕着Go去玩,而且还没有一个好的心理模型,当结构是通过价值或通过引用传递的。

这可能是一个非常愚蠢的问题,但我只是想尝试一下,看看我是否仍然在同一个对象上工作,或者我已经做了一个副本(通过值传递)。

有没有办法打印一个对象的指针(或内部ID如果指针值被gc改变)?

package main import ( "runtime" ) type Something struct { number int queue chan int } func gotest( s *Something, done chan bool ) { println( "from gotest:") println( &s ) for num := range s.queue { println( num ) s.number = num } done <- true } func main() { runtime.GOMAXPROCS(4) s := new(Something) println(&s) s.queue = make(chan int) done := make(chan bool) go gotest(s, done) s.queue <- 42 close(s.queue) <- done println(&s) println(s.number) } 

给我的窗户(8G编译版本):

 0x4930d4 from gotest: 0x4974d8 42 0x4930d4 42 

为什么go例程中的指针值显示不同的值? 原始对象上的数量确实发生了变化,因此它与同一个对象一起工作。 有没有办法看到持久性的对象ID?

Go函数参数是按值传递的。

首先,我们放弃你的例子中不相关的部分,这样我们就可以很容易地看到你只是通过价值来传递一个论点。 例如,

 package main import "fmt" func byval(q *int) { fmt.Printf("3. byval -- q %T: &q=%pq=&i=%p *q=i=%v\n", q, &q, q, *q) *q = 4143 fmt.Printf("4. byval -- q %T: &q=%pq=&i=%p *q=i=%v\n", q, &q, q, *q) q = nil } func main() { i := int(42) fmt.Printf("1. main -- i %T: &i=%pi=%v\n", i, &i, i) p := &i fmt.Printf("2. main -- p %T: &p=%pp=&i=%p *p=i=%v\n", p, &p, p, *p) byval(p) fmt.Printf("5. main -- p %T: &p=%pp=&i=%p *p=i=%v\n", p, &p, p, *p) fmt.Printf("6. main -- i %T: &i=%pi=%v\n", i, &i, i) } 

输出:

 1. main -- i int: &i=0xf840000040 i=42 2. main -- p *int: &p=0xf8400000f0 p=&i=0xf840000040 *p=i=42 3. byval -- q *int: &q=0xf8400000d8 q=&i=0xf840000040 *q=i=42 4. byval -- q *int: &q=0xf8400000d8 q=&i=0xf840000040 *q=i=4143 5. main -- p *int: &p=0xf8400000f0 p=&i=0xf840000040 *p=i=4143 6. main -- i int: &i=0xf840000040 i=4143 

在函数maini是一个intvariables,位于内存位置( &i0xf800000040 ,初始值为( i42

在函数mainp是一个指向内存位置( &p0xf8000000f0intvariables的指针,其值( p = &i0xf800000040指向一个int值( *p = i42

main函数中, byval(p)是一个函数调用,它将内存位置( &p0xf8000000f0处参数的值( p = &i0xf800000040 0xf8000000f0给内存位置( &q0xf8000000d8参数q的函数。 换句话说,为byval参数q分配了内存,并将main byval参数p值赋给了它; pq的值初始相同,但variablespq是不同的。

在函数byval ,使用作为指针p*int )的副本的指针p*int ),将整数*qi )设置为新的int值4143 。 最后在返回之前。 指针q被设置nil (零值),由于q是副本,所以对p没有影响。

在函数mainp是一个指向内存位置( &p0xf8000000f0intvariables的指针,其值( p = &i0xf800000040指向一个新的int值( *p = i4143

在函数maini是一个intvariables,在内存位置( &i0xf800000040有一个最终值( i4143

在你的例子中,用作gotest函数参数的函数mainvariabless与函数gotest参数s不一样。 它们具有相同的名称,但是具有不同范围和存储位置的不同variables。 函数参数s隐藏函数调用参数s 。 这就是为什么在我的例子中,我分别命名参数和参数variablespq来强调差异。

在你的例子中,( &s0x4930d4main函数中variabless的存储单元的地址,用作函数调用gotest(s, done)0x4974d8是函数gotest参数s 。 如果在函数gotest的末尾设置参数s = nil ,它对mainvariabless没有影响; main和最重要s是不同的存储位置。 在types方面, &s**Somethings*Something ,而*sSomething&s是指向(内存位置的地址) s的指针,它是指向(内存地址的地址)types为Something的匿名variables的指针。 根据值, main.&s != gotest.&smain.s == gotest.smain.*s == gotest.*smain.s.number == gotest.s.number

你应该采取mkb的忠告,并停止使用println(&s) 。 例如,使用fmt包,

 fmt.Printf("%v %p %v\n", &s, s, *s) 

指针指向相同的内存位置时指针具有相同的值; 当指针指向不同的内存位置时,指针有不同的值。

在Go中,参数是按值传递的。

 package main import "fmt" type SomeStruct struct { e int } // struct passed by value func v(v SomeStruct) { fmt.Printf("v: %p %v\n", &v, v) ve = 2 fmt.Printf("v: %p %v\n", &v, v) } // pointer to struct passed by value func p(p *SomeStruct) { fmt.Printf("p: %p %v\n", p, *p) pe = 2 fmt.Printf("p: %p %v\n", p, *p) } func main() { var s SomeStruct se = 1 fmt.Printf("s: %p %v\n", &s, s) v(s) fmt.Printf("s: %p %v\n", &s, s) p(&s) fmt.Printf("s: %p %v\n", &s, s) } 

输出:

 s: 0xf800000040 {1} v: 0xf8000000e0 {1} v: 0xf8000000e0 {2} s: 0xf800000040 {1} p: 0xf800000040 {1} p: 0xf800000040 {2} s: 0xf800000040 {2} 
 type sometype struct { } a := sometype {} b := int(2) println("Ptr to a", &a) println("Ptr to b", &b) 
 package main import "fmt" func zeroval(ival int) { ival = 0 } func zeroptr(iptr *int) { *iptr = 0 } func main() { i := 1 fmt.Println("initial:", i) zeroval(i) fmt.Println("zeroval:", i) //The &i syntax gives the memory address of i, ie a pointer to i. zeroptr(&i) fmt.Println("zeroptr:", i) //Pointers can be printed too. fmt.Println("pointer:", &i) } 

OUTPUT:

 $ go run pointers.go initial: 1 zeroval: 1 zeroptr: 0 pointer: 0x42131100 

如何打印 Go对象的指针值?

 package main import ( "fmt" ) func main() { a := 42 fmt.Println(&a) } 

结果是:

 0x1040a124 

指针值是什么意思?

根据维基百科 :

一个指针指向内存中的一个位置