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)))
}
标签:int,type,使用,unsafe,var,uintptr,go,Pointer
From: https://www.cnblogs.com/sooooooul/p/17502569.html