如何在Golang中转换一个包含另一个结构体的结构体?

huangapple go评论156阅读模式
英文:

How to convert a struct which has another struct in it in 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
}

我想将 Key 的实例转换为 TeamsKey。尽管底层结构相同,但我无法进行转换。

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

我得到的错误是:

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

当我在 TeamsKey 结构体中将 TeamsKeyData 更改为 KeyData 时,我可以无问题地进行转换。

问题是,为什么尽管底层结构完全相同,我仍然无法将实例彼此转换?

谢谢!

英文:

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!

答案1

得分: 1

当转换一个项目时,仅仅具有相同的布局是不够的,它们需要具有相同的底层类型,以适应它们所有的字段。在这种情况下,你最好的选择是创建一个新的目标类型的结构体,并用旧结构体的数据填充它的字段。

我尝试了一些操作,但是没有比这更好的方法。

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

英文:

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.

答案2

得分: 1

你不能以正常的方式转换或赋值不同类型的变量。但是,如果有必要,并且你确定这些结构具有相同的底层布局,你可以忽略编译器的保证并使用不安全的方式进行操作。

import "unsafe"
...
a := *((*TeamsKey)(unsafe.Pointer(&k)))
...
在没有充分理由的情况下不建议这样做你应该充分了解自己在做什么
英文:

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.

huangapple
  • 本文由 发表于 2017年9月1日 22:59:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/46003028.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定