這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
第一式 - 獲得Slice和String的記憶體資料
func stringPointer(s string) unsafe.Pointer {p := (*reflect.StringHeader)(unsafe.Pointer(&s))return unsafe.Pointer(p.Data)}func bytePointer(b []byte) unsafe.Pointer {p := (*reflect.SliceHeader)(unsafe.Pointer(&b))return unsafe.Pointer(p.Data)}
第二式 - 把[]byte轉成string
package testimport "testing"import "unsafe"func Test_ByteString(t *testing.T) {var x = []byte("Hello World!")var y = *(*string)(unsafe.Pointer(&x))var z = string(x)if y != z {t.Fail()}}func Benchmark_Normal(b *testing.B) {var x = []byte("Hello World!")for i := 0; i < b.N; i ++ {_ = string(x)}}func Benchmark_ByteString(b *testing.B) {var x = []byte("Hello World!")for i := 0; i < b.N; i ++ {_ = *(*string)(unsafe.Pointer(&x))}}這個實驗先證明了我們可以用[]byte的資料造個string給Go。接著做了兩組Benchmark,分別測試了普通的類型轉換和偽造string的效率。
PASSBenchmark_Normal 20000000 63.4 ns/opBenchmark_ByteString 2000000000 0.55 ns/opok github.com/idada/go-labs/labs28 2.486s
第三式 - 結構體和[]byte互轉
type MyStruct struct {A intB int}var sizeOfMyStruct = int(unsafe.Sizeof(MyStruct{}))func MyStructToBytes(s *MyStruct) []byte {var x reflect.SliceHeaderx.Len = sizeOfMyStructx.Cap = sizeOfMyStructx.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,))}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。