考虑两种结构相同但标签不同的类型:

type Foo struct {
  Id int64 `json:"-"`
}

type Bar struct {
  Id int64 `json:"id"`
}

不幸的是,当两种类型的标签不同并且有充分的理由时,Go 的习惯用法禁止在两种类型之间进行转换。但是我仍然需要能够控制序列化为 JSON 的数据并且不想使用 interface{} 类型。

我的问题是,使用 golang 的 unsafe.Pointer 在结构相同(但不是标签)的两种类型之间执行强制转换有多安全?就像是:
rf := &Foo{1}
rb := (*Bar)(unsafe.Pointer(rf))

是否有任何 机会导致 panic ,这可能是因为在内部,由于标签不同,两种类型中的每种数据的保存方式略有不同 是关于标签的信息与实际类型数据和数据分开保存每种类型在结构上是否相同?

编辑

为了澄清起见,我应该提到,尽管上面提供的示例使用单字段结构,但问题实际上是关于包含多个字段的结构类型。

最佳答案

严格来说, 说,这并不安全。原因是 spec 的相关部分没有为结构体的内存布局提供任何指导。它不保证内存中的字段排序、打包或对齐。理论上,编译器可以根据优化信息,决定两个看似相同的结构体根据它们的使用情况以不同的方式表示。这甚至可能是一个 Heisenbug,在 go test 构建中不会发生违规优化。

实际上 说,这不太可能发生在任何真正的编译器中,您可能可以安全地做到这一点。对于像您提供的字段结构这样的字段结构尤其如此。不过,在执行此操作之前,您可能应该通过分析来确保复制是不够的。

关于go - 只有标签不同的相同结构类型之间的不安全转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33010220/

10-16 21:49
查看更多