go 使用 unsafe 包
go 使用 unsafe 包进行指针操作
go 语言中没有直接提供指针操作,但是提供了 unsafe
包可以对指针进行转换
// - A pointer value of any type can be converted to a Pointer.
// - A Pointer can be converted to a pointer value of any type.
// - A uintptr can be converted to a Pointer.
// - A Pointer can be converted to a uintptr.
前置知识#
unsafe 包中几个类型的定义
package unsafe
// ArbitraryType is here for the purposes of documentation only and is not actually
// part of the unsafe package. It represents the type of an arbitrary Go expression.
type ArbitraryType int
// IntegerType is here for the purposes of documentation only and is not actually
// part of the unsafe package. It represents any arbitrary integer type.
type IntegerType int
type Pointer *ArbitraryType
uintptr 类型的定义
// uintptr is an integer type that is large enough to hold the bit pattern of
// any pointer.
type uintptr uintptr
提供的指针操作#
官方文档一共提供有四中方式
- 指针转换成
Pointer
;*T -> Pointer
Pointer
转换成指针;Pointer -> *T
uintptr
转换成Pointer
;uintptr -> Pointer
Pointer
转换成uintptr
;Pointer -> uintptr
普罗米修斯监控中,使用 uint64 来代表 float64 的存储,
type histogramCounts struct {
// sumBits contains the bits of the float64 representing the sum of all
// observations. sumBits and count have to go first in the struct to
// guarantee alignment for atomic operations.
// http://golang.org/pkg/sync/atomic/#pkg-note-BUG
sumBits uint64
count uint64
buckets []uint64
}
func Float64bits(f float64) uint64 {
return *(*uint64)(unsafe.Pointer(&f))
}
指针加减来获取数组的值
func TestXx1(t *testing.T) {
var a int = 5
var b float64 = 5.99
var c [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
var f Foo
var p1 = (unsafe.Pointer)(&a)
var p2 = (unsafe.Pointer)(&b)
var p3 = (unsafe.Pointer)(&c)
var p4 = (unsafe.Pointer)(&f)
t.Log(p1, p2, p3, p4)
for i := 0; i < len(c); i++ {
pp := unsafe.Pointer((uintptr(p3) + uintptr(i)*unsafe.Sizeof(c[i]))) // 当前下标对应的地址
pt := *(*int)(pp) + 3
*(*int)(pp) = *(*int)(pp) + 1 // 重新设置值
t.Log(pp, " => ", *(*int)(pp), pt, " => ", c[i], " => ", uintptr(i))
}
}
判断当前结构体是否实现接口
type test struct{}
type i interface {
Name() string
}
func (*test) Name() string {
return "test"
}
func TestIsImp(t *testing.T) {
var _ i = (*test)(nil) // 如果未实现,在编译时就会报错
var tt i = &test{}
t.Log(tt.Name())
}
字符串转换
func TestS2B(t *testing.T) {
var s = "123456"
t.Log((*[]byte)(unsafe.Pointer(&s)))
t.Log(*(*[]byte)(unsafe.Pointer(&s)))
}
作者:Soul
出处:https://www.cnblogs.com/sooooooul/p/17502569.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具