I want to restore the arguments received in type interface{} to the original type json.Unmarshal

Asked 2 years ago, Updated 2 years ago, 51 views

What I want to achieve is to create a function that simply wraps json.Unmarshal, but I would like to take the structure that I want to pass to Unmarshal as an argument of type interface{}.
 However, it has not been realized as follows.What are the options?

Step 1: Base Code

package main

import(
    "encoding/json"
    "fmt"
)

type User structure {
    Name string `json: "name"`
}

funcmain(){

    j:=[]byte(`{"name":"ando"}`)

    var user User
    if err: = json.Unmarshal(j, & user); err!=nil {
        panic(err)
    }

    fmt.Printf("%#v", user)
    // =>main.User {Name: "ando"}
}

Step 2: Pass interface{} type as it is and fail

Created an unmarshal function wrapped in json.Unmarshal.However, I passed the interface{} type directly to Unmarshal, so it came back with a map type.

func main(){

    bs: = [ ] byte (`{"name":"ando"}`)

    var user User

    _,err:=unmarshal(bs,user)
    if err!=nil{
        panic(err)
    }

}

funcunmarshal(bs[]byte, st interface{}) (interface{}, error) {

    iferr:=json.Unmarshal(bs, & st);err!=nil{
        return nil, err
    }

    fmt.Printf("%#v\n",st)
    // = > map [string] interface { } { "name" : "ando" }

    return st, nil
}

Step 3: Reflect Package Restore to Original Structure Failed

For the first time using the reflect package, I tried to restore the original structure from type interface{}, but it did not fail to decode properly.

import(
    "encoding/json"
    "fmt"
    "reflect"
)

funcunmarshal(bs[]byte, st interface{}) (interface{}, error) {

    // the intention of trying to restore the original structure
    rv: = reflect.New(reflect.TypeOf(st)) .Elem()

    iferr:=json.Unmarshal(bs, & rv);err!=nil{
        return nil, err
    }

    fmt.Printf("%#v\n",rv)
    // =>main.User {Name:"} *The value remains the initial value

    return rv, nil
}

go

2022-09-30 10:13

1 Answers

This is a self-answer (from Metropolis' comment)

I don't really understand it yet, but I was able to do the following, so I will leave it as an answer for now.

package main

import(
    "encoding/json"
    "fmt"
    "reflect"
)

type User structure {
    Name string `json: "name"`
}

funcmain(){
    bs: = [ ] byte (`{"name":"ando"}`)

    u,err:=unmarshal(bs,User{})
    if err!=nil{
        panic(err)
    }

    user: = u. (User)
    fmt.Printf("%s", user.Name)
    // =>ando
}

funcunmarshal(bs[]byte, st interface{}) (interface{}, error) {
    rv:=reflect.New(reflect.TypeOf(st)) .Interface()
    iferr:=json.Unmarshal(bs, & rv);err!=nil{
        return nil, err
    }
    return reflect.ValueOf(rv).Elem().Interface(), nil
}


2022-09-30 10:13

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.