我正在学习如何使用不安全的golang并编写此函数来编码任何对象。 我遇到两个问题,首先是剂量不安全.Sizeof(obj)总是返回obj的指针大小吗? 为什么它与reflect.TypeOf(obj).Size()不同? 其次,我要迭代obj的基础字节,并通过unsafe.Pointer()将它在TestEncode函数中转换回obj,但是对象的值都损坏了,为什么?


首先,unsafe.Sizeof返回需要存储类型的字节。这有点棘手,但这并不意味着需要存储数据的字节。

例如,众所周知,切片在32位计算机上存储3个4字节的整数。一个uintptr表示基础数组的内存地址,另外两个int32表示lencap。因此,无论分片有多长或类型是什么,分片在32位计算机上始终占用12个字节。字符串可能使用8个字节:1 uintptr用于地址,1 int32用于len

至于reflect.TypeOf().Size之间的区别,是关于接口。 reflect.TypeOf查看接口并获取具体类型,并报告有关具体类型所需的字节,而unsafe.Sizeof对于接口类型仅返回8:2 uintptr表示数据指针和方法指针列表。

第二部分现在很清楚。例如,unsafe.Pointer使用接口地址,而不是具体类型。在TestEncode中,两个unsafe.Pointer将地址发送到12字节的切片"标头"。可能还有其他错误,但是提到了这两个错误,就没有意义了。

注意:我避免谈论uintptrint32的顺序不仅是因为我不知道,而且还因为它们没有记录,不安全且依赖于执行。

注意2:结论:不要尝试转储Go数据的内存。

注意3:我将所有内容更改为32位,因为游乐场正在使用它,所以检查起来更容易。