2017-09-01 159 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