Go语言阅读小笔记,来自知呼达达关于unsafe.Pointer的分享.

Posted clnchanpin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言阅读小笔记,来自知呼达达关于unsafe.Pointer的分享.相关的知识,希望对你有一定的参考价值。

第一式 - 获得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 test

import "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的效率。

PASS
Benchmark_Normal    20000000            63.4 ns/op
Benchmark_ByteString    2000000000           0.55 ns/op
ok      github.com/idada/go-labs/labs28 2.486s

第三式 - 结构体和[]byte互转

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,
	))
}



以上是关于Go语言阅读小笔记,来自知呼达达关于unsafe.Pointer的分享.的主要内容,如果未能解决你的问题,请参考以下文章

深度解密Go语言之unsafe

Go语言:指针和unsafe.Pointer有什么区别?

Go语言 unsafe.Pointer 浅析

[阅读笔记]Go语言并发之美

golang martini 源码阅读笔记之martini核心

Go笔记-标准库的介绍