我正在做一个经常将 []int32 转换为 []byte 的项目。我创建了一个函数 intsToBytes 来执行就地转换以最小化复制。我注意到 Go 的逃逸分析没有意识到这一点ints
并bytes
引用了相同的基础数据。结果,ints
被下一个函数的堆栈数据覆盖,并继续bytes
存在并引用被覆盖的数据。
我能想到的唯一解决方案是将数据复制到一个新的字节片中。是否可以避免复制数据?
func pack() []byte {
ints := []int32{1,2,3,4,5} // This does not escape so it is allocated on the stack
bytes := intsToBytes(ints) // 'ints' and 'bytes' are different slice headers
return bytes
// After the return, the []int32{...} is deallocated and can be overwritten
// by the next function's stack data
}
func intsToBytes(i []int32) []byte {
const SizeOfInt32 = 4
// Get the slice header
header := *(*reflect.SliceHeader)(unsafe.Pointer(&i))
header.Len *= SizeOfInt32
header.Cap *= SizeOfInt32
// Convert slice header to an []byte
data := *(*[]byte)(unsafe.Pointer(&header))
/* Potentital Solution
outData := make([]byte, len(data))
copy(outData, data)
return outData
*/
return data
}