首页 >后端开发 >Golang >如何从 unsafe.Pointer 高效创建 Go 切片或数组?

如何从 unsafe.Pointer 高效创建 Go 切片或数组?

DDD
DDD原创
2024-12-06 05:04:13452浏览

How to Efficiently Create Go Slices or Arrays from unsafe.Pointer?

在 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn