原文: http://studygolang.com/articles/2909
文中大多技巧都是正确的,但是结构体和[]byte之间的转换:
第三式 - 结构体和[]byte互转 有一天,你想把一个简单的结构体转成二进制数据保存起来,这时候你想到了encoding/gob和encoding/json,做了一下性能测试,你想到效率有没有可能更高点? 于是你又试了encoding/binady,性能也还可以,但是你还不满意。但是瓶颈在哪里呢?你恍然大悟,最高效的办法就是完全不解析数据也不产生数据啊! 怎么做?是时候使用这个黑魔法了: type MyStruct struct { A int B int } var sizeOfMyStruct = int(unsafe.Sizeof(MyStruct{})) func MyStructToBytes(s *MyStruct) []byte { var x reflect.SliceHeader x.Len = sizeOfMyStruct x.Cap = sizeOfMyStruct x.Data = uintptr(unsafe.Pointer(s)) return *(*[]byte)(unsafe.Pointer(&x)) } func BytesToMyStruct(b []byte) *MyStruct { return (*MyStruct)(unsafe.Pointer( (*reflect.SliceHeader)(unsafe.Pointer(&b)).Data, )) }原文中结构体转切片时,将结构体的指针赋给[]byte的data字段([]byte本来就是reflect.sliceheader结构体,用unsafe.sizeof能看到他的长度为24,另外结构体中的interface{}长度是16,大概8个字节存数据指针,8个字节存类型吧,我猜,,,),这是ok的,但是切片转结构体的时候,居然用&b (type *[]byte)这种形式, 这个&b是切片这个结构体即sliceheader的指针,这是gc管理的,怎么可以作为指针转换成结构体呢?应该用&b[0],&b[0]相当于b.data
有疑问加站长微信联系(非本文作者)