【go】指针的风骚操作(结合unsafe.point与uintptr)

dongzaidong · · 1284 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

指针是具有类型的

总所周知,声明的变量都是有具体类型的,而对于存储指针的变量是否有类型,有时是一头雾水,在此做一个小总结,指针是具有类型的。
就如:

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]

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


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:dongzaidong

查看原文:【go】指针的风骚操作(结合unsafe.point与uintptr)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1284 次点击  
加入收藏 微博
上一篇:2020-04-06
下一篇:Golang文件操作
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传