How to read interface value with structure address

WBOY
Release: 2024-02-10 19:21:08
forward
768 people have browsed it

How to read interface value with structure address

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!

Question content

I have a variable with data type interface{} and pass it the address of the structure. Now I can't read the fields

from the interface

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
Copy after login

If I use res.data.username I get an error

How to read structure fields from the interface?

Workaround

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)
}
Copy after login

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
}
Copy after login

The output is:

main.DBBatch
map[string]interface {}
*main.DBBatch
*main.DBBatch
Copy after login

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!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template