在 Golang 中从 unsafe.Pointer 创建切片或数组:一种有效的替代方案
指向数组的指针可以表示为 Golang 中的 uintptr 值。然而,当指针存储为 uintptr 时,访问原始数组可能会很困难。
低效方法:内存复制
一种简单的方法是从将指针指向新切片:
data := make([]byte, size) stepSize := unsafe.Sizeof(data[0]) for i := 0; i < size; i++ { data[i] = *(*byte)(unsafe.Pointer(p)) p += stepSize }
此方法效率低下,因为它涉及复制数据,这可能是对于大数组来说比较耗时。
高效方法:Reflect.SliceHeader
更高效的方法是使用reflect.SliceHeader创建切片或数组,而不需要复制内存:
var data []byte sh := (*reflect.SliceHeader)(unsafe.Pointer(&data)) sh.Data = p sh.Len = size sh.Cap = size fmt.Println(data)
该方法将uintptr转换为reflect.SliceHeader并修改其字段指向现有数组。生成的切片或数组将与原始数组共享相同的底层内存。
替代方法:复合文字
另一种替代方法是使用复合文字来创建Reflect.SliceHeader:
sh := &reflect.SliceHeader{ Data: p, Len: size, Cap: size, } data := *(*[]byte)(unsafe.Pointer(sh)) fmt.Println(data)
此方法产生与之前相同的结果
注意事项
使用 uintptr 指针时,确保原始数组在指针的整个生命周期内保持有效非常重要。此外,由于 unsafe 包对类型安全有潜在影响,因此应谨慎使用。
以上是如何从 unsafe.Pointer 高效创建 Go 切片或数组?的详细内容。更多信息请关注PHP中文网其他相关文章!