|
有没有办法打印对象的指针(或内部 id,若指针值为 gc 更改)?
" q. y8 k2 L/ K, X+ Q) I- W# n
' c7 v1 [; c5 S. m" E- package mainimport ( "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 在我的 Windows 上给出(8g 编译版本):[code]0x4930d4from gotest:0x4974d8420x4930d442
% f& N( }/ [* l/ H q% W 为什么 go 例程中的指针值显示不同的值?原始对象的数量确实发生了变化,因此可以使用相同的对象。有没有办法检查持久的对象 ID?" P- u0 R* [$ l% Y0 s- }* e
5 E1 ]( }! S8 T1 Y. I0 W6 y. k$ i 解决方案:
. y' D8 {# U' }" [+ S" e Go 函数参数按值传递。7 R s% l3 |2 a) E/ M& v
首先,让我们丢弃示例中不相关的部分,这样我们就可以很容易地看到你只是按值传递参数。' }8 {5 g3 w* c+ X5 M
package mainimport "fmt"func byval(q *int) fmt.Printf("3. byval -- q %T: &q=%p q=&i=%p *q=i=%v\n",q,&q,q,*q) *q = 4143 fmt.Printf("4. byval -- q %T: &q=%p q=&i=%p *q=i=%v\n",q,&q,q,*q) q = nil}func main() i := int(42) fmt.Printf("1. main -- i %T: &i=%p i=%v\n",i,&i,i) p := &i fmt.Printf("2. main -- p %T: &p=%p p=&i=%p *p=i=%v\n",p,&p,p,*p) byval(p) fmt.Printf("5. main -- p %T: &p=%p p=&i=%p *p=i=%v\n",p,&p,p,*p) fmt.Printf("6. main -- i %T: &i=%p i=%v\n",i,&i,i)}
! B8 ?2 C0 f$ r6 v7 ^# s ]5 W 输出:# z1 n$ x: }9 e5 U6 @
1. main -- i int: &i=0xf840000040 i=422. main -- p *int: &p=0xf8400000f0 p=&i=0xf840000040 *p=i=423. byval -- q *int: &q=0xf8400000d8 q=&i=0xf840000040 *q=i=424. byval -- q *int: &q=0xf8400000d8 q=&i=0xf840000040 *q=i=41435. main -- p *int: &p=0xf8400000f0 p=&i=0xf840000040 *p=i=41436. main -- i int: &i=0xf840000040 i=4143 B/ h4 \& }- z( N$ `$ U) L& H
在函数中main,i是int内存位置 ( &i)处的变量,0xf i) 42。/ |$ ]! V" r- ^- T
在函数中main,p是指向int内存位置 ( &p)变量指针0xf8000000f其值 ( p= &i)0xf800000040指向一个int值 ( *p= i) 42。8 n5 w0 l& u5 s# Y
在功能main,byval(p)是函数调用,其将值(p= &i)0xf存储位置(自变量)&p)0xf8000000f0给函数byval参数q在存储器位置(&q)0xf8000000d8.换句话说,存储器被分配用于byval参数q和的值main byval的参数p分配给它; 值p和q最初是相同的,但变量p和q是不同的。1 M4 f9 N! _4 X; e e
在功能byval,使用指针q(*int),它是指针的副本p(*int),整数*q(i)被设置为新的int值4143。最后回来指针q设置为nil(零值),这对p因为q副本没有影响。, L& t8 t9 D! m a4 b$ l$ E& m1 O
在函数中main,p是一个指向int内存位置 ( &p)变量指针0xf8000000f其值 ( p= &i)0xf800000040指向一个新int值 ( *p= i) 4143。
; d- I/ P0 L# j( h# b+ X8 ~在函数中main,i是int内存位置 ( &i)处的变量,0xf i) 4143。; ^. l0 c$ q$ b6 Q+ q
在您的示例中,用作函数调用参数的函数main变量不同于函数参数。它们有相同的名称,但它们有不同的功能域和内存位置。函数参数隐藏了函数调用参数。这就是为什么在我的例子中,我命名参数和参数变量并强调差异。s``gotest``gotest``s``s``s``p``q
' n/ _4 ?* ^+ m, I7 Q9 L+ M/ F( &s)0x4930d4是s函数main内存位置地址用作函数调用参数的变量gotest(s,done),并且0x4974d8是函数gotest参数内存位置地址s。如果s = nil设置函数末尾的参数gotest,则对变量sin没有影响main;sinmain和singotest内存位置不同。在类型方面,&sis **Something、sis*Something和*sis Something。&s指向(内存位置地址)s的指针,它指向(内存位置地址)类型的匿名变量的指针Something. 就值而言main.&s != gotest.&s,main.s == gotest.s、main.*s == gotest.*s、 和main.s.number == gotest.s.number。
* F" A) I9 t( }+ o* ?, \你应该接受 mkb 明智建议并停止使用println(&s). 使用fmt包,例如,2 f2 Q7 W8 C7 k" {' n
fmt.Printf("%v %p %v\n",&s,s,*s)% L2 J* o& I! ?( b! S
指针指向同一内存位置时具有相同的值;指针指向不同的内存位置时具有不同的值。 |
|