Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > Go unsafe.Pointer类型

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

作者:Kevin666

unsafe.Pointer 是 Go 语言标准库 unsafe 包中的一个特殊类型,用于在不同类型的指针之间进行 无类型转换,允许你绕过 Go 的类型系统进行底层操作,感兴趣的可以了解一下

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

🎯 使用场景

和普通指针的区别

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类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文