(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另外一个地方的值。因为经过地址能找到所需的变量单元,能够说,地址指向该变量单元。所以,将地址形象化的称为“指针”。意思是经过它能找到以它为地址的内存单元。一个指针变量指向了一个值的内存地址。编程
Go语言支持指针类型*T
,指针的指针**T
,以及包含包名前缀的*package.T
。安全
在指针类型变量前面加上 *(取值符)来获取指针所指向的内容。
在值类型变量前面加上 &(取地址符)来获取该变量的指针。编程语言
声明一个int值的指针变量ui
var ip *int
声明一个string值的指针变量spa
var sp *string
经过 :=
语法来定义指针指针
var str string = "春生" sp := &str
声明一个int值的指针的指针变量code
var p **int
声明一个time.Time值的指针变量对象
var t *time.Time
打印变量在内存中的地址:blog
package main import "fmt" func main() { var str string = "oldboy" fmt.Printf("变量的地址: %x\n", &str) }
运行结果:ip
变量的地址: c42000e1d0
当一个指针被定义后没有分配到任何变量时,它的值为 nil。nil 指针也称为空指针。
nil在概念上和其它语言的null、None、nil、NULL同样,都指代零值或空值。
package main import ( "fmt" ) func main() { var ip *int var sp *string if ip == nil { fmt.Println("ip == nil") } if sp == nil { fmt.Println("sp == nil") } }
定义的不一样类型的零值不能用于比较运算,实例以下:
package main import ( "fmt" ) func main() { var ip *int var sp *string if ip == sp { fmt.Println("error") } }
编译错误:
./main.go:11:8: invalid operation: ip == sp (mismatched types *int and *string)
查看零值指针类型,实例以下:
package main import ( "fmt" ) func main() { var ip *int var sp *string fmt.Printf("ip : %#v\n", ip) fmt.Printf("sp : %#v\n", sp) }
运行结果:
ip : (*int)(nil) sp : (*string)(nil)
Go语言是不容许两个指针类型进行转换的。
咱们通常使用T做为一个指针类型,表示一个指向类型T变量的指针。为了安全的考虑,两个不一样的指针类型不能相互转换,好比 *uint 不能转为 *int 。实例以下:
package main func main() { var i uint = 10 var p2 *int p1 := &i p2 = (*int)(p1) }
编译错误:
./main.go:8:13: cannot convert p1 (type *uint) to type *int
unsafe.Pointer类型用于表示任意类型的指针。有4个特殊的只能用于Pointer类型的操做:
一、 任意类型的指针能够转换为一个Pointer类型值
二、 一个Pointer类型值能够转换为任意类型的指针
三、 一个uintptr类型值能够转换为一个Pointer类型值
四、 一个Pointer类型值能够转换为一个uintptr类型值
所以,Pointer类型容许程序绕过类型系统读写任意内存。使用它时必须谨慎。实例以下:
package main import ( "fmt" "unsafe" ) func main() { var i uint = 10 var p2 *int p1 := &i p2 = (*int)(unsafe.Pointer(p1)) fmt.Println(*p2) }