通过一段代码了解 goalng string 和 slice 的底层实现,

YuPeng · · 228 次点击 · 开始浏览    置顶

通过将 string 和 slice 转换为runtime 中的 slice 和 stringStruct 类型 然后 通过 指针获取下标的值。 ```go package main import ( "fmt" "unsafe" ) type slice struct { array unsafe.Pointer len int cap int } type stringStruct struct { str unsafe.Pointer len int } func main() { ///// string //// str := "hello" strStruct := (*stringStruct)(unsafe.Pointer(&str)) for i := 0; i < strStruct.len; i++ { fmt.Printf("%c ", *(*byte)(unsafe.Pointer(uintptr(strStruct.str) + uintptr(i)*unsafe.Sizeof(byte(0))))) // 获取每字节的值 } fmt.Printf("\n-----------------\n") //// slice //// bytes := []byte("Hello, 世界") bytesSlice := (*slice)(unsafe.Pointer(&bytes)) for i := 0; i < bytesSlice.len; i++ { fmt.Printf("%d ", *(*byte)(unsafe.Pointer(uintptr(bytesSlice.array) + uintptr(i)*unsafe.Sizeof(byte(0))))) } fmt.Printf("\n-----------------\n") int8s := []int8{0, 9, 8, 7, 6, 90, 89, 87} int8sSlice := (*slice)(unsafe.Pointer(&int8s)) for i := 0; i < int8sSlice.len; i++ { fmt.Printf("%d ", *(*int8)(unsafe.Pointer(uintptr(int8sSlice.array) + uintptr(i)*unsafe.Sizeof(int8(0))))) } fmt.Printf("\n-----------------\n") int16s := []int16{0, 9, 8, 7, 6, 90, 89, 87, 800} int16Slice := (*slice)(unsafe.Pointer(&int16s)) for i := 0; i < int16Slice.len; i++ { fmt.Printf("%d ", *(*int16)(unsafe.Pointer(uintptr(int16Slice.array) + uintptr(i)*unsafe.Sizeof(int16(0))))) } fmt.Printf("\n-----------------\n") strings := []string{"hello", "世界", "golang"} stringsSlice := (*slice)(unsafe.Pointer(&strings)) for i := 0; i < stringsSlice.len; i++ { fmt.Printf("%s ", *(*string)(unsafe.Pointer(uintptr(stringsSlice.array) + uintptr(i)*unsafe.Sizeof(string(""))))) //unsafe.Sizeof(string(""))=16 } fmt.Printf("\n-----------------\n") } ```

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

228 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传