How to convert a struct which has another struct in it in Golang?

5.6k views Asked by At

I have a model like the following:

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
}

I want to convert an instance of Key to TeamsKey. Although the underlying structure is same, I cannot convert it.

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

The error I got:

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

When I change TeamsKeyData to KeyData in TeamsKey struct, I can convert the struct without problem.

The question is, why can't I convert the instances to each other even though the underlying structure is exactly the same?

Thanks!

2

There are 2 answers

0
Milo Christiansen On

When converting an item it is not enough for them to have identical layouts, they need to have the same underlying type for all their fields.

In this case the best you can do is to make a new struct of the type you want and fill out it's fields with data from the old struct.

I played around some with this, but I was not able to do better than that.

I assume that the two KeyData types need different method sets? If this is not the case, you should just use the same type both places.

4
Uvelichitel On

You can't convert or assign variables of different types normal way. But if it's necessary and you are certain the strutures have the same underlying layout, you can omit compiler's guarantee and do it unsafe.

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

It's not recommended without serious reasons, you should well understand what you do.