2017-09-01 187 views
0

我有类似下面的模式:如何转换Golang中包含其他结构的结构?

type TeamsKey struct { 
    KeyData TeamsKeyData 
    Fingerprint string 
    Algorithm string 
    Encoding string 
    Usage string 
} 

type TeamsKeyData struct { 
    KeyId string 
    Key string 
    Description string 
    ExpiresAt string 
    CreatedAt string 
} 

type Key struct { 
    KeyData  KeyData 
    Fingerprint string 
    Algorithm string 
    Encoding string 
    Usage  string 
} 

type KeyData struct { 
    KeyId  string 
    Key   string 
    Description string 
    ExpiresAt string 
    CreatedAt string 
} 

我想关键的一个实例转换TeamsKey。虽然底层结构相同,但我无法将其转换。

func main() { 
    k := Key{} 
    a := TeamsKey(k) 
} 

我得到的错误:

tmp/sandbox251934449/main.go:46:15: cannot convert k (type Key) to type TeamsKey 

当我在TeamsKey结构改变TeamsKeyDataKeyData,我可以转换结构没有问题。

问题是,为什么我不能将实例转换为对方,即使底层结构完全相同?

谢谢!

+2

它不是相同的整体结构,类型转换需要相同的基础类型:https://golang.org/ref/spec#Conversions – JimB

+1

鉴于此场景,您可以做的最好的方法是编写一个采用该类型的函数,创建新的,手动分配所有的字段,然后返回它。或重构,所以你没有两个相同的结构...只是一个。 – RayfenWindspear

+0

@JimB所以这意味着即使嵌套的结构体也具有相同的基础结构(TeamsKeyData和KeyData),因为TeamsKeyData和KeyData不是同一类型,所以不可能将一个结构转换为另一个结构? – user2604150

回答

1

转换项目时,它们不足以让它们具有相同的布局,它们是need to have the same underlying type for all their fields

在这种情况下,您可以做的最好的方法是创建一个您想要的类型的新结构,并使用旧结构中的数据填充它的字段。

我在这里玩过一些,但是我没能做得比那更好。

我假设两个KeyData类型需要不同的方法集?如果这是而不是这种情况,则应该只是使用相同类型的两个地方。

0

您无法正常转换或分配不同类型的变量。但是,如果有必要并且您确定该结构具有相同的底层布局,则可以省略编译器的保证并进行不安全。

import "unsafe" 
... 
a := *((*TeamsKey)(unsafe.Pointer(&k))) 
... 

不建议没有严重的原因,你应该很好地理解你做什么。

+0

我个人不能宽恕建议有人绕过不完全理解他们的类型。 – RayfenWindspear

+0

所以我应该更好地删除答案?但技术上我们可以做到。 – Uvelichitel

+2

添加一些关于这不是一个好主意的好警告,我会删除downvote。最大的问题是这可能会导致随机恐慌。对一个结构的看似良性的改变突然造成恐慌,难以追查。 – RayfenWindspear