Go 在函数中传递接口切片,并将其解组到其项中
我是否可以将转换为Go 在函数中传递接口切片,并将其解组到其项中,go,parameters,interface,slice,unmarshalling,Go,Parameters,Interface,Slice,Unmarshalling,我是否可以将转换为[]接口{}的结构片传递到函数中,填充它并在函数结束工作后使用 下面是问题的完整示例 简短描述: type DBResponse struct { Rows int `json:"rows"` Error string `json:"error"` Value json.RawMessage `json:"value"` } type User struct { Id int `json:"i
[]接口{}
的结构片传递到函数中,填充它并在函数结束工作后使用
下面是问题的完整示例
简短描述:
type DBResponse struct {
Rows int `json:"rows"`
Error string `json:"error"`
Value json.RawMessage `json:"value"`
}
type User struct {
Id int `json:"id"`
Name string `json:"name"`
}
func loadDBRows(p []interface{}) {
var response DBResponse
someDataFromDB := []byte("{\"rows\":1, \"error\": \"\", \"value\": {\"name\":\"John\", \"id\":2}}")
json.Unmarshal(someDataFromDB, &response)
json.Unmarshal(response.Value, &p[0])
fmt.Println(p)//p[0] filled with map, not object
}
func main() {
users := make([]User, 5)
data := make([]interface{}, 5)
for i := range users {
data[i] = users[i]
}
loadDBRows(data)
}
对于单个接口{}
,这个问题很容易解决,您可以在完整的示例中进行测试。为什么我不能为slice解决它
我想做这件事而不去思考!有没有“真正的方法”可以在没有反射和映射[string]接口{}的情况下将通用json解析器写入选定的数据结构?不需要复杂的代码和额外的操作
谢谢你的帮助 因为
p
是接口的一部分,所以在这一行json.Unmarshal(response.Value,&p[0])
您将指向接口{}
的指针传递给用户
,因为json.Unmarshal
允许接口作为数据解组的目的地,所以它不会查看接口{}
用于另一种类型,只需将json
解码为map
您可以做的是让接口{}
已经是一个指向具体类型的指针,例如数据[i]=&users[i]
,然后您只需将接口{}
传递给json.Unmarshal
func loadDBRows(p []interface{}) {
var response DBResponse
someDataFromDB := []byte("{\"rows\":1, \"error\": \"\", \"value\": {\"name\":\"John\", \"id\":2}}")
json.Unmarshal(someDataFromDB, &response)
json.Unmarshal(response.Value, p[0]) // notice the missing &
fmt.Println(p)
}
users := make([]User, 5)
data := make([]interface{}, 5)
for i := range users {
data[i] = &users[i] // notice the added &
}
一个选项是使用reflect包访问切片元素 该函数假定
p
是一个切片:
func loadDBRows(p interface{}) {
var response DBResponse
someDataFromDB := []byte("{\"rows\":1, \"error\": \"\", \"value\": {\"name\":\"John\", \"id\":2}}")
json.Unmarshal(someDataFromDB, &response)
v := reflect.ValueOf(p). // get reflect.Value for argument
Index(0). // get first element assuming that p is a slice
Addr(). // take address of the element
Interface() // get the pointer to element as an interface{}
json.Unmarshal(response.Value, v)
}
像这样使用loadDBRows
。没有必要像问题中那样创建[]接口{}
:
func main() {
users := make([]User, 5)
loadDBRows(users)
fmt.Println(users)
}
非常感谢!我应该读更多关于接口转换的内容,你能给我一个建议吗?再次感谢!对于
json.Unmarshal
的转换规则,最好阅读并更好地理解接口{}
是什么,可以找到一篇很好的文章