从字节切片到不安全结构的类型转换
Type conversion from byte slice to struct with unsafe
我正在尝试了解为什么我的 Go 代码无法按我预期的方式运行。当我执行这个测试时,它失败了:
func TestConversion(t *testing.T) {
type myType struct {
a uint8
value uint64
}
myVar1 := myType{a: 1, value: 12345}
var copyFrom []byte
copyFromHeader := (*reflect.SliceHeader)(unsafe.Pointer(©From))
copyFromHeader.Data = uintptr(unsafe.Pointer(&myVar1))
copyFromHeader.Cap = 9
copyFromHeader.Len = 9
copyTo := make([]byte, len(copyFrom))
for i := range copyFrom {
copyTo[i] = copyFrom[i]
}
myVar2 := (*myType)(unsafe.Pointer(©From[0]))
myVar3 := (*myType)(unsafe.Pointer(©To[0]))
if myVar2.value != myVar3.value {
t.Fatalf("Expected myVar3.value to be %d, but it is %d", myVar2.value, myVar3.value)
}
}
输出将是:
slab_test.go:67: Expected myVar3.value to be 12345, but it is 57
但是,如果我在复制数据之前将 copyFromHeader.Data
增加 1
,则一切正常。像这样:
copyFromHeader.Data = uintptr(unsafe.Pointer(&myVar1)) + 1
我不明白为什么它似乎将基础数据移动了一个字节。
a
和value
之间有7个填充字节。您仅在 value
中获得 12345 (57) 的最低有效字节。当你将copyFrom
向下移动一个字节时,myVar2.value
和myVar3.value
的值都是48(12345的第二个字节),所以你的测试通过了。如果将 9 更改为 16,它应该可以工作。
您以这种方式复制结构有什么特殊原因吗?
我正在尝试了解为什么我的 Go 代码无法按我预期的方式运行。当我执行这个测试时,它失败了:
func TestConversion(t *testing.T) {
type myType struct {
a uint8
value uint64
}
myVar1 := myType{a: 1, value: 12345}
var copyFrom []byte
copyFromHeader := (*reflect.SliceHeader)(unsafe.Pointer(©From))
copyFromHeader.Data = uintptr(unsafe.Pointer(&myVar1))
copyFromHeader.Cap = 9
copyFromHeader.Len = 9
copyTo := make([]byte, len(copyFrom))
for i := range copyFrom {
copyTo[i] = copyFrom[i]
}
myVar2 := (*myType)(unsafe.Pointer(©From[0]))
myVar3 := (*myType)(unsafe.Pointer(©To[0]))
if myVar2.value != myVar3.value {
t.Fatalf("Expected myVar3.value to be %d, but it is %d", myVar2.value, myVar3.value)
}
}
输出将是:
slab_test.go:67: Expected myVar3.value to be 12345, but it is 57
但是,如果我在复制数据之前将 copyFromHeader.Data
增加 1
,则一切正常。像这样:
copyFromHeader.Data = uintptr(unsafe.Pointer(&myVar1)) + 1
我不明白为什么它似乎将基础数据移动了一个字节。
a
和value
之间有7个填充字节。您仅在 value
中获得 12345 (57) 的最低有效字节。当你将copyFrom
向下移动一个字节时,myVar2.value
和myVar3.value
的值都是48(12345的第二个字节),所以你的测试通过了。如果将 9 更改为 16,它应该可以工作。
您以这种方式复制结构有什么特殊原因吗?