一段有关unsafe.Pointer有意思的代码

colinrs · 2020-07-18 23:31:24 · 919 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2020-07-18 23:31:24 的主题,其中的信息可能已经有所发展或是发生改变。

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    bytes := []byte{104, 101, 108, 108, 111}
    p := unsafe.Pointer(&bytes) //强制转换成unsafe.Pointer,编译器不会报错
    str := *(*string)(p)        //然后强制转换成string类型的指针,再将这个指针的值当做string类型取出来
    fmt.Println(str)            // 输出 "hello"
    bytes[0] = 106
    fmt.Println(str) // 输出 "jello"
}

unsafe.Pointer

出于安全考虑,Go 语言并不支持直接操作内存,但它的标准库中又提供一种不安全(不保证向后兼容性) 的指针类型unsafe.Pointer,让程序可以灵活的操作内存。

unsafe.Pointer的特别之处在于,它可以绕过 Go 语言类型系统的检查,与任意的指针类型互相转换。也就是说,如果两种类型具有相同的内存结构(layout),我们可以将unsafe.Pointer当做桥梁,让这两种类型的指针相互转换,从而实现同一份内存拥有两种不同的解读方式。

比如说,[]byte和string其实内部的存储结构都是一样的,但 Go 语言的类型系统禁止他俩互换。如果借助unsafe.Pointer,我们就可以实现在零拷贝的情况下,将[]byte数组直接转换成string类型。


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

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

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