如何打印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
在函数main
, i
是一个int
variables,位于内存位置( &i
) 0xf800000040
,初始值为( i
) 42
。
在函数main
, p
是一个指向内存位置( &p
) 0xf8000000f0
的int
variables的指针,其值( p
= &i
) 0xf800000040
指向一个int
值( *p
= i
) 42
。
在main
函数中, byval(p)
是一个函数调用,它将内存位置( &p
) 0xf8000000f0
处参数的值( p
= &i
) 0xf800000040
0xf8000000f0
给内存位置( &q
) 0xf8000000d8
参数q
的函数。 换句话说,为byval
参数q
分配了内存,并将main
byval
参数p
值赋给了它; p
和q
的值初始相同,但variablesp
和q
是不同的。
在函数byval
,使用作为指针p
( *int
)的副本的指针p
( *int
),将整数*q
( i
)设置为新的int值4143
。 最后在返回之前。 指针q
被设置nil
(零值),由于q
是副本,所以对p
没有影响。
在函数main
, p
是一个指向内存位置( &p
) 0xf8000000f0
的int
variables的指针,其值( p
= &i
) 0xf800000040
指向一个新的int
值( *p
= i
) 4143
。
在函数main
, i
是一个int
variables,在内存位置( &i
) 0xf800000040
有一个最终值( i
) 4143
。
在你的例子中,用作gotest
函数参数的函数main
variabless
与函数gotest
参数s
不一样。 它们具有相同的名称,但是具有不同范围和存储位置的不同variables。 函数参数s
隐藏函数调用参数s
。 这就是为什么在我的例子中,我分别命名参数和参数variablesp
和q
来强调差异。
在你的例子中,( &s
) 0x4930d4
是main
函数中variabless
的存储单元的地址,用作函数调用gotest(s, done)
, 0x4974d8
是函数gotest
参数s
。 如果在函数gotest
的末尾设置参数s = nil
,它对main
variabless
没有影响; main
和最重要s
是不同的存储位置。 在types方面, &s
是**Something
, s
是*Something
,而*s
是Something
。 &s
是指向(内存位置的地址) s
的指针,它是指向(内存地址的地址)types为Something
的匿名variables的指针。 根据值, main.&s != gotest.&s
, main.s == gotest.s
, main.*s == gotest.*s
和main.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
指针值是什么意思?
根据维基百科 :
一个指针指向内存中的一个位置