Home >Backend Development >Golang >How to read interface value with structure address

How to read interface value with structure address

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBforward
2024-02-10 19:21:08802browse

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

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)
}

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!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete