如何在Golang中向元素类型不是命名类型的切片中追加元素?

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

How to append to a slice whose element type is not a named type in golang

问题

我有两个结构体:

  1. type ResponseQueryHotel struct {
  2. QueryString *string `json:"queryString"`
  3. Status string `json:"status"`
  4. Action string `json:"action"`
  5. RefCode string `json:"refCode"`
  6. Vendorid string `json:"vendorid"`
  7. SearchToken *string `json:"searchtoken"`
  8. Data struct {
  9. Hotels []struct {
  10. Data ResponseQueryHotelsData `json:"data"`
  11. } `json:"hotels"`
  12. } `json:"data"`
  13. }
  14. type ResponseQueryHotelsData struct {
  15. Hotelidvendor string `json:"hotelidvendor"`
  16. Hotelname string `json:"hotelname"`
  17. Hoteladdress string `json:"hoteladdress"`
  18. Hoteldistrict string `json:"hoteldistrict"`
  19. Hotelcity string `json:"hotelcity"`
  20. Hotelprovince string `json:"hotelprovince"`
  21. Hotelcountry string `json:"hotelcountry"`
  22. Hotellat string `json:"hotellat"`
  23. Hotellng string `json:"hotellng"`
  24. Hotelprice string `json:"hotelprice"`
  25. Hoteldiscountprice string `json:"hoteldiscountprice"`
  26. Hotelphotourl string `json:"hotelphotourl"`
  27. }

现在我需要向ResponseQueryHotel.Data.Hotels添加项目,其中元素类型不是命名类型。所以我尝试了这样做:

  1. var output models.ResponseQueryHotel
  2. var data models.ResponseQueryHotelsData
  3. output.Data.Hotels = append(output.Data.Hotels, data)

但是我得到了这个错误:

  1. cannot use data (variable of type models.ResponseQueryHotelsData) as struct{Data models.ResponseQueryHotelsData "json:\"data\""} value in argument to append

我应该怎么做才能向output.Data.Hotels添加项目(将会有多个ResponseQueryHotelsData要添加)。

顺便说一下,我不能更改这些结构体(超出了我的控制)。

英文:

I have two structs:

  1. type ResponseQueryHotel struct {
  2. QueryString *string `json:"queryString"`
  3. Status string `json:"status"`
  4. Action string `json:"action"`
  5. RefCode string `json:"refCode"`
  6. Vendorid string `json:"vendorid"`
  7. SearchToken *string `json:"searchtoken"`
  8. Data struct {
  9. Hotels []struct {
  10. Data ResponseQueryHotelsData `json:"data"`
  11. } `json:"hotels"`
  12. } `json:"data"`
  13. }
  14. type ResponseQueryHotelsData struct {
  15. Hotelidvendor string `json:"hotelidvendor"`
  16. Hotelname string `json:"hotelname"`
  17. Hoteladdress string `json:"hoteladdress"`
  18. Hoteldistrict string `json:"hoteldistrict"`
  19. Hotelcity string `json:"hotelcity"`
  20. Hotelprovince string `json:"hotelprovince"`
  21. Hotelcountry string `json:"hotelcountry"`
  22. Hotellat string `json:"hotellat"`
  23. Hotellng string `json:"hotellng"`
  24. Hotelprice string `json:"hotelprice"`
  25. Hoteldiscountprice string `json:"hoteldiscountprice"`
  26. Hotelphotourl string `json:"hotelphotourl"`
  27. }

Now I need to append items to ResponseQueryHotel.Data.Hotels, whose element type is not a named name. So I try this:

  1. var output models.ResponseQueryHotel
  2. var data models.ResponseQueryHotelsData
  3. output.Data.Hotels = append(output.Data.Hotels, data)

But I get this error:

  1. cannot use data (variable of type models.ResponseQueryHotelsData) as struct{Data models.ResponseQueryHotelsData "json:\"data\""} value in argument to append

What should I do to append items to output.Data.Hotels (there will be more than 1 ResponseQueryHotelsData to append).

And BTW I can't change the structs (it's out of my control).

答案1

得分: 2

如果需要多次使用相同的底层类型,可以定义一个别名:

  1. type Hotel = struct {
  2. Data ResponseQueryHotelsData `json:"data"`
  3. }
  4. hotels := []Hotel{
  5. {Data: ResponseQueryHotelsData{}},
  6. {Data: ResponseQueryHotelsData{}},
  7. }
  8. output.Data.Hotels = append(output.Data.Hotels, hotels...)

如果只需要一次使用该结构类型,可以直接在现场声明:

  1. hotels := []struct {
  2. Data ResponseQueryHotelsData `json:"data"`
  3. }{
  4. {Data: ResponseQueryHotelsData{}},
  5. {Data: ResponseQueryHotelsData{}},
  6. }
  7. output.Data.Hotels = append(output.Data.Hotels, hotels...)

在《Go语言规范》的可赋值性部分中指出:

> 如果满足以下条件之一,类型为 V 的值 x 可以赋值给类型为 T 的变量("x 可以赋值给 T"):
>
> - V 和 T 是相同的类型。
> - V 和 T 具有相同的底层类型,但不是类型参数,并且 V 或 T 中至少有一个不是命名类型。
> - V 和 T 是具有相同元素类型的通道类型,V 是双向通道,并且 V 或 T 中至少有一个不是命名类型。
> - T 是接口类型(但不是类型参数),并且 x 实现了 T。
> - x 是预声明的标识符 nil,T 是指针、函数、切片、映射、通道或接口类型(但不是类型参数)。
> - x 是可以用类型 T 的值表示的无类型常量。

英文:

Define an alias to the identical underlying type if you need to use it multiple times:

  1. type Hotel = struct {
  2. Data ResponseQueryHotelsData `json:"data"`
  3. }
  4. hotels := []Hotel{
  5. {Data: ResponseQueryHotelsData{}},
  6. {Data: ResponseQueryHotelsData{}},
  7. }
  8. output.Data.Hotels = append(output.Data.Hotels, hotels...)

Or declare the struct type in place if you only need it once:

  1. hotels := []struct {
  2. Data ResponseQueryHotelsData `json:"data"`
  3. }{
  4. {Data: ResponseQueryHotelsData{}},
  5. {Data: ResponseQueryHotelsData{}},
  6. }
  7. output.Data.Hotels = append(output.Data.Hotels, hotels...)

The Assignability section in the golang spec states:

> A value x of type V is assignable to a variable of type T ("x is assignable to T") if one of the following conditions applies:
>
> - V and T are identical.
> - V and T have identical underlying types but are not type parameters and at least one of V or T is not a named type.
> - V and T are channel types with identical element types, V is a bidirectional channel, and at least one of V or T is not a named type.
> - T is an interface type, but not a type parameter, and x implements T.
> - x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type, but not a type parameter.
> - x is an untyped constant representable by a value of type T.

答案2

得分: 0

你可以将字段Data.Hotels的类型更改为[]ResponseQueryHotelsData,而不是struct。

英文:

You can change type of field Data.Hotels to []ResponseQueryHotelsData instead of struct.

huangapple
  • 本文由 发表于 2023年4月8日 15:26:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75963880.html
匿名

发表评论

匿名网友

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

确定