【简介】
指针的值是一个变量的地址
一个指针指示值所保存的位置
使用指针可以在无须知道变量名字的情况下间接读取或更新变量的值
var i int
p=&i
获取一个指向整型变量的指针,它的类型是整型指针(*int)。
其余类型的如下面例子
package main
import (
"fmt"
)
type myinter interface{}
func main() {
var myint int
var mystr string
var mybool bool
var myfloat float64
var myinterface myinter
myintp := &myint
mystrp := &mystr
myboolp := &mybool
myfloatp := &myfloat
myinterfacep := &myinterface
checkType(myintp)
checkType(mystrp)
checkType(myboolp)
checkType(myfloatp)
checkType(myinterfacep)
}
func checkType(i interface{}) {
fmt.Printf(" type is %T ,value is %v\n", i, i)
}
执行结果如下
type is *int ,value is 0xc4200140b0
type is *string ,value is 0xc42000e1d0
type is *bool ,value is 0xc4200140b8
type is *float64 ,value is 0xc4200140c0
type is *main.myinter ,value is 0xc42000e1e0
【go语言指针的特点】
1、零值是nil
2、不能进行指针运算
3.、指针是可以比较的 (两个指针当且仅当指向同一个变量或者都为nil的情况下才相等)
4、函数返回局部变量的地址是安全的
只声明未赋值的变量,golang都会自动为其初始化为零值。指针变量的零值 是 nil。
其余基础类型的零值如下
package main
import (
"fmt"
)
func main() {
var myint int
var mybool bool
var mystr string
var myptr *int
var myintarr [5]int
var mystrarr [5]string
fmt.Printf("myint is %T,and default value is %v\n", myint, myint)
fmt.Printf("mybool is %T,and default value is %v\n", mybool, mybool)
fmt.Printf("mystr is %T,and default value is %v\n", mystr, mystr)
fmt.Printf("myptr is %T,and default value is %v\n", myptr, myptr)
fmt.Printf("myintarr is %T,and default value is %v\n", myintarr[0:], myintarr[0:])
fmt.Printf("mystrarr is %T,and default value is %v\n", mystrarr[0:], mystrarr[0:])
}
执行结果如下
myint is int,and default value is 0
mybool is bool,and default value is false
mystr is string,and default value is
myptr is *int,and default value is <nil>
myintarr is []int,and default value is [0 0 0 0 0]
mystrarr is []string,and default value is [ ]
###
go语言返回局部变量的地址是安全的,如下demo
package main
import "fmt"
func main() {
p1 := f()
fmt.Println("&p1 is:", &p1)
fmt.Println("p1 is:", p1)
fmt.Println("*P1 is:", *p1)
p2 := f()
fmt.Println("&p2 is:", &p2)
fmt.Println("p2 is:", p2)
fmt.Println("*P2 is:", *p2)
p3 := f()
fmt.Println("&p3 is:", &p3)
fmt.Println("p3 is:", p3)
fmt.Println("*P3 is:", *p3)
}
func f() *int {
v := 1
return &v
}
执行结果如下,可以发现&v 局部变量每次返回值都不一样
&p1 is: 0xc42000c028
p1 is: 0xc4200140a0
*P1 is: 1
&p2 is: 0xc42000c038
p2 is: 0xc4200140b8
*P2 is: 1
&p3 is: 0xc42000c040
p3 is: 0xc4200140c8
*P3 is: 1
###
【demo 指针对于值的修改】
package main
import "fmt"
func main() {
v := 1
fmt.Println("begin v is:", v)
incr(&v) //调用一次incr,v+1
fmt.Println("after incr(&v) v is:", v)
fmt.Println(incr(&v))
fmt.Println(incr(&v))
fmt.Println(incr(&v))
fmt.Println(incr(&v))
fmt.Println("final v is:", v)
}
func incr(p *int) int {
(*p)++
return *p
}
执行结果,v的值发生改变
begin v is: 1
after incr(&v) v is: 2
3
4
5
6
final v is: 6
###
修改上面代码,变为值传递,如下
package main
import "fmt"
func main() {
v := 1
fmt.Println("begin,v is:", v)
incr(v)
fmt.Println(incr(v))
fmt.Println(incr(v))
fmt.Println(incr(v))
fmt.Println(incr(v))
fmt.Println("after,v is:", v)
}
func incr(p int) int {
p++
return p
}
执行结果如下,即v的值没有变化
begin,v is: 1
2
2
2
2
after,v is: 1