|
有没有办法打印对象的指针(或内部 id,若指针值为 gc 更改)?
9 J2 _' u' p0 o0 a6 \' c% N0 [' m
- 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
2 J3 d+ B# l. r. b4 F 为什么 go 例程中的指针值显示不同的值?原始对象的数量确实发生了变化,因此可以使用相同的对象。有没有办法检查持久的对象 ID?( C0 Y* o% e6 n) W* B* k5 n
* v4 _ i3 T' f% \ 解决方案:
# n% r% M( U8 Y0 L! ^) @# \ Go 函数参数按值传递。
5 R8 X' H. N9 ^. g% @! v; f' `首先,让我们丢弃示例中不相关的部分,这样我们就可以很容易地看到你只是按值传递参数。5 w4 e& {( E- h6 t+ _# E
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)}
/ p& Y6 f) t5 E$ K: N2 C 输出:
2 ]. Z9 I( N0 ]% ?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
- J9 t$ [1 ~6 n7 F: v Y# x 在函数中main,i是int内存位置 ( &i)处的变量,0xf i) 42。
3 x( ~6 ^! u3 V$ t6 o在函数中main,p是指向int内存位置 ( &p)变量指针0xf8000000f其值 ( p= &i)0xf800000040指向一个int值 ( *p= i) 42。5 U7 Z3 m/ n, Q- O8 ~# C- o+ Q1 d
在功能main,byval(p)是函数调用,其将值(p= &i)0xf存储位置(自变量)&p)0xf8000000f0给函数byval参数q在存储器位置(&q)0xf8000000d8.换句话说,存储器被分配用于byval参数q和的值main byval的参数p分配给它; 值p和q最初是相同的,但变量p和q是不同的。
4 i! A3 L- H- w1 z, G在功能byval,使用指针q(*int),它是指针的副本p(*int),整数*q(i)被设置为新的int值4143。最后回来指针q设置为nil(零值),这对p因为q副本没有影响。
: z) k' X; X0 O2 Y5 C2 s在函数中main,p是一个指向int内存位置 ( &p)变量指针0xf8000000f其值 ( p= &i)0xf800000040指向一个新int值 ( *p= i) 4143。( u- B! {7 X( Y+ y% g2 q$ j
在函数中main,i是int内存位置 ( &i)处的变量,0xf i) 4143。* ]) l" \: k {1 M [
在您的示例中,用作函数调用参数的函数main变量不同于函数参数。它们有相同的名称,但它们有不同的功能域和内存位置。函数参数隐藏了函数调用参数。这就是为什么在我的例子中,我命名参数和参数变量并强调差异。s``gotest``gotest``s``s``s``p``q
/ r a3 H- B% z" _; Y5 J- ?( &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。
" @. j5 b* l& Q1 N1 K3 [0 N* r0 Q: O- Q你应该接受 mkb 明智建议并停止使用println(&s). 使用fmt包,例如,1 w% @5 v* g: V$ g
fmt.Printf("%v %p %v\n",&s,s,*s)
4 L! |4 {- s8 ^9 k5 i+ K 指针指向同一内存位置时具有相同的值;指针指向不同的内存位置时具有不同的值。 |
|