最近搞golang接口测试,有点费劲,被这个地址&、指针*给搞蒙了,之前用java的时候,貌似没有这些玩意,在这里记录一下学习笔记
现在记录一下&、*的作用:
&:是取地址符号
*:可以表示一个变量是指针类型(例如:*int32),也可以表示指针变量的地址(*p4)
这里有一个结构体person:
type Person struct { Name string Age int32 }
思考一个问题:什么时候应该用&person{},什么时候应该用*person 什么时候该用person{}呢???
p1 := Person{Name: "xiaowang", Age: 15} p2 := &p1 p3 := *p2 p4 := &p2 p5 := *p4 p1.Age = 19 fmt.Printf("p1:%+vn", p1) fmt.Printf("p2:%+vn", p2) fmt.Printf("p3:%+vn", p3) fmt.Printf("p4:%+vn", p4) fmt.Printf("p5:%+vn", p5)
打印结果 p1:{Name:xiaowang Age:19}//直接打印了person p2:&{Name:xiaowang Age:19} //p2是&p1 p3:{Name:xiaowang Age:15}//p3是从p2这个地址取到的值,前面说了*代表从地址中取值,这里p2就是个地址,*p2就是从p2这个地址取对应的值,而age=15,因为这个p1是个值类型。 p4:0x13406140 //打印了p2的地址 p5:&{Name:xiaowang Age:19} //打印了p1的地址
弄到这里,捋一下:
换一种打印方法,直接将地址打出来
fmt.Printf("p1:%vn", p1) fmt.Printf("p2:%pn", p2) fmt.Printf("p3:%vn", p3) fmt.Printf("p4:%pn", p4) fmt.Printf("p5:%pn", p5)
打印结果 p1:{xiaowang 19} p2:0x134940d0 //p2变成了地址,也就是p1的实际地址值 p3:{xiaowang 15} p4:0x13488130 p5:0x134940d0
1.为啥p1的age=19:后面修改了age:p1.Age = 19,因此 p1的值就变了。
2.为啥p2的age=19:现在看到了 p2实际上是p1的地址,这个值实际上是不变的,因为p1的地址没变,只是fmt的打印编码问题使这个问题混乱了,p2 := &p1,p1={xiaowang 19},p2 = &{xiaowang 19},没毛病,因此实际上p2压根没变,因为&{xiaowang 19}和原来的&{xiaowang 15}的地址是一个值。
3.为啥p3的age=15,p3:=*p2,p2是个地址,此时赋值时,p2这个地址指向的就是 {xiaowang 15},这是个赋值语句,将这个值赋值给了p3,p3 = {xiaowang 15}.后面p1变不变的对他没有影响了。
4.这里p4 := &p2, p4里存储的也是一个地址,这里存储的是p2的地址,因此这里打出来是个地址
5.p5 := *p4,也就是p5的值,是从根据p4地址取的值,也就是p2的地址。
这下清晰了,*是从地址里取值,&是获取地址
什么时候用* 什么时候用&,也跟使用场景有关系了,假如定义一个结构体变量用不用指针呢,如果要在其他方法中修改这个结构体值,那么就用指针,不需要修改值就不用,用指针代表是引用类型,不用就是值类型,与java中值类型、引用类型概念一致。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)