【Go】指针 | new函数 | 变量的生命周期
1 package main 2 3 import ( 4 "fmt" 5 ) 6 7 // 1.每次调用f()都会返回不同的结果 8 // 2.因为指针包含了一个变量的地址,因此如果将指针作为参数调用函数,那将可以在函数中通过该指针来 更新变量的值。 9 // 3.每次我们对一个变量取地址,或者复制指针,我们都是为原变量创建了新的别名。 10 // 4.对于在包一级声明的变量来说,它们的生命周期和整个程序的运行周期是一致的。 11 // 5.在局部变量的声明周期则是动态的:从每次创建一个新变量的声明语句开始,直到该变量不再被引用为止,然后变量的存储空间可能被回收。函数的参数变量和返回值变量都是局部变量。它们在函数每次被调用的时候创建。 12 // 6.可以通过包一级的变量找到的变量必须在堆上分配(从函数中逃逸),逃逸的变量需要额外分配内存,同时对性能的优化可能会产生细微的影响。 13 // 7.将指向短生命周期对象的指针保存到具有长生命周期的对象中,特别是保存到全局变量时,会阻止对短生命周期对象的垃圾回收(从而可能影响程序的性能)。 14 var p = f() 15 16 func main() { 17 fmt.Println("=====================") 18 x := 1 19 p := &x 20 fmt.Println(p) //0xc42000e240 21 fmt.Println("==更新指针所指向的变量的值==") 22 *p = 2 23 fmt.Println(x) //2 24 fmt.Println("==指针之间进行相等测试==") 25 var i, j int 26 fmt.Println(&i == &i, &i == &j, &i == nil) //true false false 27 fmt.Println("==获取调用f函数时创建局部变量v的地址==") 28 fmt.Println(p) 29 fmt.Println("==通过指针来更新变量的值==") 30 a := 1 31 incr(&a) 32 fmt.Println(incr(&a)) //3 33 34 fmt.Println("==new()==") 35 b := new(int) 36 fmt.Println(*b) //0 37 *b = 10 38 fmt.Println(*b) //10 39 40 } 41 42 func f() *int { 43 v := 1 44 return &v 45 } 46 47 func incr(p *int) int { 48 *p++ //只增加p指向的变量的值,并不改变p指针 49 return *p 50 }