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

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

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

问题

我有两个结构体:

type ResponseQueryHotel struct {
	QueryString *string `json:"queryString"`
	Status      string  `json:"status"`
	Action      string  `json:"action"`
	RefCode     string  `json:"refCode"`
	Vendorid    string  `json:"vendorid"`
	SearchToken *string `json:"searchtoken"`
	Data        struct {
		Hotels []struct {
			Data ResponseQueryHotelsData `json:"data"`
		} `json:"hotels"`
	} `json:"data"`
}

type ResponseQueryHotelsData struct {
	Hotelidvendor      string `json:"hotelidvendor"`
	Hotelname          string `json:"hotelname"`
	Hoteladdress       string `json:"hoteladdress"`
	Hoteldistrict      string `json:"hoteldistrict"`
	Hotelcity          string `json:"hotelcity"`
	Hotelprovince      string `json:"hotelprovince"`
	Hotelcountry       string `json:"hotelcountry"`
	Hotellat           string `json:"hotellat"`
	Hotellng           string `json:"hotellng"`
	Hotelprice         string `json:"hotelprice"`
	Hoteldiscountprice string `json:"hoteldiscountprice"`
	Hotelphotourl      string `json:"hotelphotourl"`
}

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

var output models.ResponseQueryHotel

var data models.ResponseQueryHotelsData
output.Data.Hotels = append(output.Data.Hotels, data)

但是我得到了这个错误:

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:

type ResponseQueryHotel struct {
	QueryString *string `json:"queryString"`
	Status   string `json:"status"`
	Action   string `json:"action"`
	RefCode  string `json:"refCode"`
	Vendorid string `json:"vendorid"`
	SearchToken *string `json:"searchtoken"`
	Data     struct {
		Hotels []struct {
			Data ResponseQueryHotelsData `json:"data"`
		} `json:"hotels"`
	} `json:"data"`
}

type ResponseQueryHotelsData struct {
	Hotelidvendor      string `json:"hotelidvendor"`
	Hotelname          string `json:"hotelname"`
	Hoteladdress       string `json:"hoteladdress"`
	Hoteldistrict      string `json:"hoteldistrict"`
	Hotelcity          string `json:"hotelcity"`
	Hotelprovince      string `json:"hotelprovince"`
	Hotelcountry       string `json:"hotelcountry"`
	Hotellat           string `json:"hotellat"`
	Hotellng           string `json:"hotellng"`
	Hotelprice         string `json:"hotelprice"`
	Hoteldiscountprice string `json:"hoteldiscountprice"`
	Hotelphotourl 	   string `json:"hotelphotourl"`
}

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

var output models.ResponseQueryHotel

var data models.ResponseQueryHotelsData
output.Data.Hotels = append(output.Data.Hotels, data)

But I get this error:

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

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

type Hotel = struct {
	Data ResponseQueryHotelsData `json:"data"`
}
hotels := []Hotel{
	{Data: ResponseQueryHotelsData{}},
	{Data: ResponseQueryHotelsData{}},
}

output.Data.Hotels = append(output.Data.Hotels, hotels...)

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

hotels := []struct {
	Data ResponseQueryHotelsData `json:"data"`
}{
	{Data: ResponseQueryHotelsData{}},
	{Data: ResponseQueryHotelsData{}},
}

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:

type Hotel = struct {
	Data ResponseQueryHotelsData `json:"data"`
}
hotels := []Hotel{
	{Data: ResponseQueryHotelsData{}},
	{Data: ResponseQueryHotelsData{}},
}

output.Data.Hotels = append(output.Data.Hotels, hotels...)

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

hotels := []struct {
	Data ResponseQueryHotelsData `json:"data"`
}{
	{Data: ResponseQueryHotelsData{}},
	{Data: ResponseQueryHotelsData{}},
}

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:

确定