在我的 playground 代码中,有 2 种类型共享非常相似的字段定义,如下所示,
type Int64 int64
type TA struct {
A Int64
B string
}
type TB struct {
A int64
B string
}
如何以最少的代码和性能成本在两者之间进行转换?
https://play.golang.org/p/VFERyT-RgK
附注经过测试,只有在 TA.A 与 TB.A 类型完全相同的情况下,TA(some_tb_value) 才会起作用,如上例。但是,使基础类型 (Int64->int64) 完全相同并不适合我需要的用例。
附注使用某种协议(protocol) (json) 序列化 some_tb_value 并反序列化回 TA 类型的指针是可能的,但它对于关键路径的使用来说可能太重了
最佳答案
由于它们是不同的结构类型,因此您无法转换它们。
一种解决方案是使用反射(reflect
包)来复制字段。
而且由于它们具有相同的内存布局,另一种解决方案是使用包 unsafe
:
func main() {
var a TA = TA{1, "I'm TA"}
var b TB = TB{2, "I'm TB"}
fmt.Println(TA2TB(&a), TB2TA(&b))
}
func TA2TB(a *TA) *TB {
return (*TB)(unsafe.Pointer(a))
}
func TB2TA(b *TB) *TA {
return (*TA)(unsafe.Pointer(b))
}
输出(在 Go Playground 上尝试):
&{1 I'm TA} &{2 I'm TB}
但是要知道,使用 unsafe
会丢失所有类型安全检查。如果将来类型被修改,代码将继续编译,但在运行时可能会出现神秘错误(如果你幸运的话,运行时 panic ,在更坏的情况下无声的行为不端,在最坏的情况下完全崩溃)。
最好重构您的代码并使用相同的底层类型,这样您就可以简单地执行一个类型 conversion .
关于go - 将 TypeA 转换为 TypeB,其中基础字段类型相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38653943/