Go语言通过指针和unsafe包支持底层内存操作,可用于系统编程与高性能数据结构。①指针基础:使用&取地址、解引用;②unsafe.Pointer实现跨类型指针转换,如int转*float64;③unsafe.Offsetof计算结构体字段偏移;④结合uintptr进行指针算术,模拟动态数组遍历。需谨慎避免未定义行为。

Go语言虽然为开发者提供了内存安全的编程环境,但在某些需要直接操作内存的场景下,比如底层系统编程、高性能数据结构实现等,可以通过指针和unsafe包突破限制。这要求程序员对内存布局有清晰理解,否则容易引发崩溃或未定义行为。
指针基础操作
Go中的指针与C类似,用于指向变量的内存地址。通过&取地址,*解引用。
示例:
package mainimport "fmt"func main() { a := 42 p := &a // p是指向a的指针 fmt.Println(*p) // 输出: 42 *p = 100 // 修改a的值 fmt.Println(a) // 输出: 100}
使用unsafe.Pointer转换类型
unsafe.Pointer可以看作任意类型的指针,能够在*T和unsafe.Pointer之间自由转换,实现跨类型访问内存。
立即学习“go语言免费学习笔记(深入)”;
常见用途:将一个类型的指针转为另一个类型指针,例如*int转为*float64。
package mainimport ( "fmt" "unsafe")func main() { i := int(42) pi := &i pf := (*float64)(unsafe.Pointer(pi)) // 强制转换指针类型 fmt.Println(*pf) // 解释同一块内存为float64(结果可能无意义)}
注意:上面的例子只是演示类型转换机制,实际解释整型内存为浮点可能导致不可预测结果。
计算结构体字段偏移量
利用unsafe.Offsetof可以获取结构体字段相对于结构体起始地址的偏移,常用于序列化、反射优化等。
package mainimport ( "fmt" "unsafe")type Person struct { Name string Age int32 ID int64}func main() { p := Person{} fmt.Printf("Name offset: %dn", unsafe.Offsetof(p.Name)) // 通常为0 fmt.Printf("Age offset: %dn", unsafe.Offsetof(p.Age)) fmt.Printf("ID offset: %dn", unsafe.Offsetof(p.ID))}
输出会显示各字段在结构体中的字节偏移,可用于手动内存解析。
直接操作内存:模拟动态数组
结合unsafe.Pointer和uintptr,可实现类似C语言的指针算术,遍历连续内存块。
package mainimport ( "fmt" "unsafe")func main() { arr := [5]int{10, 20, 30, 40, 50} ptr := unsafe.Pointer(&arr[0]) size := unsafe.Sizeof(arr[0]) // 每个int大小 for i := 0; i < len(arr); i++ { // 计算第i个元素地址 elemPtr := (*int)(unsafe.Add(ptr, uintptr(i)*size)) fmt.Printf("arr[%d] = %dn", i, *elemPtr) }}
这里用unsafe.Add安全地进行指针偏移,避免直接使用uintptr加减带来的风险。
基本上就这些。unsafe能力强大但危险,只应在必要时使用,并确保内存对齐和生命周期可控。
以上就是Golang指针与unsafe包内存操作示例的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1412557.html
微信扫一扫
支付宝扫一扫