In Go language, interface is a very powerful and flexible type. However, we may encounter some confusion when trying to read the structure address in an interface value. So, how do you read an interface value that has a struct address? In this article, we'll answer this question for you and provide some practical tips and sample code. Whether you are a beginner or an experienced Go developer, this article will help you. Let’s take a look!
I have a variable with data type interface{}
and pass it the address of the structure. Now I can't read the fields
code show as below:
type UserData struct { UserID string `json:"user_id"` UserName string `json:"user_name"` } type Result struct { Status string `json:"status"` Data interface{} `json:"data"` } var res Result res.Data = &UserData json.Unmarshal([]byte(`{"status": "success", "data": {"user_id":15,"user_name":"abc"}}`), &res) fmt.Println(res.Data) //working fine fmt.Println(res.Data.UserName) //getting error: type interface{} has no field or method UserName
If I use res.data.username
I get an error
How to read structure fields from the interface?
Compare this with golang Why do fields that don't exist in go structs still exist after marshaling said struct to json. At first I thought they were the same. But it turned out not to be the case.
For this question, res.data
has values of type *userdata
. So a simple type assertion will do.
package main import ( "encoding/json" "fmt" ) type userdata struct { userid string `json:"user_id"` username string `json:"user_name"` } type result struct { status string `json:"status"` data interface{} `json:"data"` } func main() { var res result res.data = &userdata{} json.unmarshal([]byte(`{"status": "success", "data": {"user_id":15,"user_name":"abc"}}`), &res) fmt.println(res.data) fmt.println(res.data.(*userdata).username) }
The following demo is a merge of two demos by @mkopriva which shows the differences:
package main import ( "encoding/json" "fmt" "log" ) type dbbatch struct { fieldtokeep string `json:"field_to_keep"` fieldtokeep2 string `json:"field_to_keep2"` } func main() { jsonbatch := `{"field_to_keep":"xxxxx","field_to_keep2":"26400527","field_to_delete":"whynotdeleted"}` var i interface{} = dbbatch{} fmt.printf("%t\n", i) // type is dbbatch if err := json.unmarshal([]byte(jsonbatch), &i); err != nil { log.println(err) } fmt.printf("%t\n", i) // type is not dbbatch anymore, instead it's map[string]any i = &dbbatch{} fmt.printf("%t\n", i) // type is *dbbatch if err := json.unmarshal([]byte(jsonbatch), &i); err != nil { log.println(err) } fmt.printf("%t\n", i) // type is *dbbatch }
The output is:
main.DBBatch map[string]interface {} *main.DBBatch *main.DBBatch
The above is the detailed content of How to read interface value with structure address. For more information, please follow other related articles on the PHP Chinese website!