Go语言阅读小笔记,来自知呼达达关于unsafe.Pointer的分享.
2023-09-11 14:15:00 时间
第一式 - 获得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 语言学习之路(笔记)
- 【Go命令教程】3. go install
- 《Go学习笔记 . 雨痕》流程控制(if、switch、for range、goto、continue、break)
- 【Go语言】【8】GO语言的条件语句和选择语句
- 【Go语言】【4】GO语言类型和为类型增加方法
- 【Go语言】【3】GO语言常量
- 【Go语言】【15】GO语言的面向对象
- 【Go语言】【13】再谈GO语言的结构体
- go安装goctl进行Go Dockefile的自动生成
- [Go] go基础4
- [Go] go build 和 go install 的区别
- [Go] golang 替换组件包 更新 go.mod, go.sum 的方式
- [Go] go-nsq 使用指南
- [Go] Viper 加载项目配置,go build 打包配置文件进二进制
- Atitit golang开发环境搭建 目录 1. 编辑helo.go1 1.1. 调试编译1 2. Ide选择liteide2 3. 问题解决2 4. 附录2 4.1. Go语言标准库常
- 我的Go+语言初体验——【一、go+环境WIN10_100%成功安装(附-视频)】
- 【Go基础】使用go语言函数
- 【Go应用】go实现rpc通信协议
- Go语言自学系列 | go语言中的流程控制
- Go语言自学系列 | go语言切片的遍历
- Go语言自学系列 | go语言遍历map
- go语言笔记——append底层实现和Cpp vector无异,只是有返回值,double后返回了新的vector地址而已
- go语言笔记——包的概念本质上和java是一样的,通过大小写来区分private,fmt的Printf不就是嘛!
- go语言笔记——是c开发的 lex yacc进行词法和语法分析,go不支持函数和运算符重载,不支持类型继承,也不支持断言,还有泛型
- GO语言教程(一)Linux( Centos)下Go的安装, 以及HelloWorld
- Mac上搭建Go语言环境及第一个hello.go程序