英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论