【golang】指针的风骚操作(结合unsafe.point与u
2020-04-06 本文已影响0人
dongzd
指针是具有类型的
总所周知,声明的变量都是有具体类型的,而对于存储指针的变量是否有类型,有时是一头雾水,在此做一个小总结,指针是具有类型的。
就如:
var c int
fmt.Println(reflect.TypeOf(c))
d := &c
fmt.Println(reflect.TypeOf(d))
结果:
int
*int
那可能一些人就会有疑问,指针既然具有类型,那指针之间可以进行类型转换吗。就如下面一样操作
#(*Type)ptr
a := (*int)(&xx)
在Go 的指针是不支持指针运算和转换
下面就详细说一下指针类型怎么互相转换
不同类型指针的互相转换
go语言是强语言类型,不同类型,不可以跨类型计算、赋值等操作。
如下:
num := 2
p := &num
fp := (*float32)(p)
fmt.Println(fp)
./main.go:27:18: cannot convert p (type *int) to type *float32
针对上述错误示例,那在go中怎么进行任意类型指针转换呢?
这里就引入go语言自带包unsafe.Pointer
其核心为:
- 任意类型的指针值均可转换为 Pointer。
- Pointer 均可转换为任意类型的指针值。
- uintptr 均可转换为 Pointer。
- Pointer 均可转换为 uintptr。
这里的uintptr是一个整数类型,可以进行指针运算,后面会介绍其中用
num := 2
p := &num
fp := (*float32)(unsafe.Pointer(p))
fmt.Println(reflect.TypeOf(fp))
*float32
到这里基本了解go中指针怎么类型转换与unsafe.pointer作用。
讲完指针转换,下面在介绍一下指针运算。
通过指针地址去获取/设置变量值是程序中所有方法中最快的
go语言中指针式不可以进行指针运算的,这里就引入go语言的自有类型uintptr:是golang的内置类型,是能存储指针的整型
下面我们通过指针地址操作来给数组赋值:
(这只是一个简单的demo,其高效可以拥有string与byte转换或者struct赋值)
//通过指针给数组第二位赋值
var arr [3]int
// 获取首地址指针
point := unsafe.Pointer(&arr[0])
fmt.Println(point)
// 指针偏移 获取首地址所占字节数,对指针地址进行偏移,获取第二个数的指针地址
ptr := uintptr(point) + unsafe.Sizeof(arr[0])
// 转换为通用指针类型
k := unsafe.Pointer(ptr)
//转为数组的指针类型,并且进行皆引用获取指针指向的内存值重新赋值为88(初始为0)
*(*int)(k) = 88
fmt.Println(arr)
0xc000014160
[0 88 0]
上述为本人工作一下总结,如有不对请指正