golang 编程笔记

【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
其核心为:

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]

上述为本人工作一下总结,如有不对请指正

上一篇下一篇

猜你喜欢

热点阅读