Go中unsafe.Pointer类型的使用小结

 更新时间:2026年02月05日 09:39:49   作者:Kevin666  
unsafe.Pointer 是 Go 语言标准库 unsafe 包中的一个特殊类型,用于在不同类型的指针之间进行 无类型转换,允许你绕过 Go 的类型系统进行底层操作,感兴趣的可以了解一下

unsafe.Pointer 是 Go 语言标准库 unsafe 包中的一个特殊类型,用于在不同类型的指针之间进行 无类型转换,允许你绕过 Go 的类型系统进行底层操作,属于“不安全”的操作。

🎯 使用场景

  • 类型不兼容的指针转换(例如从 *int 转为 *float64)
  • 与 uintptr 配合操作底层内存地址
  • 修改只读字段(例如字符串的只读字节)
  • 实现类似 C 的结构体偏移访问

和普通指针的区别

unsafe.Pointer 和普通的 &T 指针(即 *T)在 Go 中有本质上的区别

类型说明
*T是类型安全的指针,指向类型 T 的数据。编译器知道它的类型信息,能自动进行内存对齐、类型检查等。
unsafe.Pointer是一种通用的无类型指针,可以转换为任意类型的指针或从任意类型的指针转换过来。编译器不检查其指向的类型和用法。

✅ 示例 1:不同类型指针转换

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	var x int = 100
	// 将 *int 转换为 *float64(不安全!仅用于演示)
	p := unsafe.Pointer(&x)
	f := (*float64)(p) // 假装 x 是 float64
	fmt.Println(*f)    // 输出不确定,因为解释方式不对
}

❗这是错误用法,仅作为类型转换的演示。实际运行会出现乱码或未定义行为。

✅ 示例 2:uintptr与unsafe.Pointer配合做地址偏移(字段偏移)

package main

import (
	"fmt"
	"unsafe"
)

type Person struct {
	age   int
	score float64
}

func main() {
	p := Person{age: 25, score: 98.5}
	// 获取结构体首地址
	ptr := unsafe.Pointer(&p)

	// 偏移到第二个字段(score)
	scorePtr := (*float64)(unsafe.Pointer(uintptr(ptr) + unsafe.Offsetof(p.score)))
	fmt.Println(*scorePtr) // 输出:98.5
}

✅ 示例 3:修改字符串的只读内容(危险行为)

package main

import (
	"fmt"
	"reflect"
	"unsafe"
)

func main() {
	s := "hello"
	sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
	// 强转为字节数组指针修改内容
	b := (*[5]byte)(unsafe.Pointer(sh.Data))
	b[0] = 'H'
	fmt.Println(s) // 输出 "Hello"
}

❗这是标准库明确禁止的行为,仅作教学展示。在某些平台上可能 crash!

✅ 小结

场景是否安全推荐使用
类型间转换(*T1 ➜ *T2)
与 uintptr 搭配偏移操作
直接操作底层数据(如字符串修改)

到此这篇关于Go中unsafe.Pointer类型的使用小结的文章就介绍到这了,更多相关Go unsafe.Pointer类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解析go语言调用约定多返回值实现原理

    解析go语言调用约定多返回值实现原理

    这篇文章主要为大家介绍了解析go语言调用约定多返回值实现原理,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • Golang中的同步工具sync.Map示例详解

    Golang中的同步工具sync.Map示例详解

    sync.Map是Golang标准库提供的并发安全的Map类型,可以在多个goroutine并发读写Map的场景下不需要加锁,这篇文章主要介绍了Golang中的同步工具sync.Map详解,需要的朋友可以参考下
    2023-05-05
  • Golang 官方依赖注入工具wire示例详解

    Golang 官方依赖注入工具wire示例详解

    这篇文章主要为大家介绍了Golang 官方依赖注入工具wire示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • Go 指针、uintptr、unsafe.Pointer之间如何转换

    Go 指针、uintptr、unsafe.Pointer之间如何转换

    本文详细介绍了Go语言中普通指针(*T)、uintptr和unsafe.Pointer的区别与转换,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-07-07
  • golang中的单引号转义问题

    golang中的单引号转义问题

    这篇文章主要介绍了golang中的单引号转义问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • GoFrame错误处理常用方法及错误码使用示例

    GoFrame错误处理常用方法及错误码使用示例

    这篇文章主要为大家介绍了GoFrame错误处理常用方法及错误码使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • 一文带你理解Go语言中方法的本质

    一文带你理解Go语言中方法的本质

    我们知道,Go语言从设计伊始,就不支持经典的面向对象语法元素,但 Go 语言仍保留了名为“方法(method)”的语法元素,下面我们就来带大家深入了解一下Go语言中的方法吧
    2023-11-11
  • GoFrame gredis配置文件及配置方法对比

    GoFrame gredis配置文件及配置方法对比

    这篇文章主要为大家介绍了GoFrame gredis配置管理中,配置文件及配置方法对比,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • 详解Go flag实现二级子命令的方法

    详解Go flag实现二级子命令的方法

    这篇文章主要介绍了Go flag 详解,实现二级子命令,本文就探讨一下 Go 语言中如何写一个拥有类似特性的命令行程序,需要的朋友可以参考下
    2022-07-07
  • Golang使用ttl机制保存内存数据方法详解

    Golang使用ttl机制保存内存数据方法详解

    ttl(time-to-live) 数据存活时间,我们这里指数据在内存中保存一段时间,超过期限则不能被读取到,与Redis的ttl机制类似。本文仅实现ttl部分,不考虑序列化和反序列化
    2023-03-03

最新评论