1 struct <-> bytes
type MyStruct struct {
a int
b int
}
func main() {
var ms = &MyStruct{a: 1, b: 2}
// struct 转 byte[]
bytes := StructToBytes(ms)
fmt.Printf("%#v\n", bytes)
// byte[] 转 struct
ms2 := (*MyStruct)(BytesToStruct(bytes))
fmt.Printf("%#v", ms2)
}
func StructToBytes(obj interface{}) []byte {
var x reflect.SliceHeader
length := binary.Size(obj)
x.Len = length
x.Cap = length
x.Data = reflect.ValueOf(obj).Pointer()
return *(*[]byte)(unsafe.Pointer(&x))
}
func BytesToStruct(buf []byte) unsafe.Pointer {
return unsafe.Pointer(
(*reflect.SliceHeader)(unsafe.Pointer(&buf)).Data,
)
}
// a_test.go
package haha
import (
"fmt"
"reflect"
"sync"
"sync/atomic"
"testing"
"time"
"unsafe"
)
func TestFloat(t *testing.T) {
i := 10
f := *(*float64)(unsafe.Pointer(&i))
fmt.Println(f, reflect.TypeOf(f))
}
type MyInt int
func TestConvert(t *testing.T) {
a := []int{1, 2, 3, 4}
b := *(*[]MyInt)(unsafe.Pointer(&a))
fmt.Println(b) // [1 2 3 4]
}
func TestAtomic(t *testing.T) {
var shareBufPtr unsafe.Pointer
writeDataFn := func() {
data := []int{}
for i := 0; i < 100; i++ {
data = append(data, i)
}
// 使shareBufPtr指向data
atomic.StorePointer(&shareBufPtr, unsafe.Pointer(&data))
}
readDataFn := func() {
data := atomic.LoadPointer(&shareBufPtr)
fmt.Println(data, *(*[]int)(data))
}
var wg sync.WaitGroup
writeDataFn()
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
for i := 0; i < 10; i++ {
writeDataFn()
time.Sleep(time.Microsecond * 100) // 100us
}
wg.Done()
}()
wg.Add(1)
go func() {
for i := 0; i < 10; i++ {
readDataFn()
time.Sleep(time.Microsecond * 100) // 100us
}
wg.Done()
}()
}
wg.Wait()
}