Trying to unmarshal data into interface in golang - go

Trying to unmarshal data into interface. It is working fine. But If i access res.page or res.Page not working
I got the below error:
res.Page undefined (type interface {} is interface with no methods)
Below is my code:
package main
import (
"encoding/json"
"fmt"
)
func main() {
var res interface{}
str := `{"page": 1, "fruits": ["apple", "peach"]}`
json.Unmarshal([]byte(str), &res)
fmt.Println(res.Page)
}
Thanks in advance.

interface{} specifies zero methods (and ofc zero fields).
What you need is a map[string]interface{}
Try this https://play.golang.org/p/WBwXKob4zdA
package main
import (
"encoding/json"
"fmt"
)
func main() {
var res map[string]interface{}
str := `{"page": 1, "fruits": ["apple", "peach"]}`
json.Unmarshal([]byte(str), &res)
fmt.Println(res["page"])
}
You may want to check:
https://tour.golang.org/methods/14
https://tour.golang.org/methods/15

Related

How to pass interface pointer through a function in Golang?

I was testing golang functionalities and came across this concept where I can use a pointer of an interface as an interface itself. In the below code, how do I ensure that the value of one changes to random.
package main
import (
"fmt"
)
func some(check interface{}) {
check = "random"
}
func main() {
var one *interface{}
some(one)
fmt.Println(one)
}
Specifically, I need ways in which I can pass an interface pointer to a function which accepts an interface as an argument.
Thanks!
Accept a pointer to interface{} as the first parameter to some
Pass the address of one to some
package main
import (
"fmt"
)
func some(check *interface{}) {
*check = "random"
}
func main() {
var one interface{}
some(&one)
fmt.Println(one)
}
https://play.golang.org/p/ksz6d4p2f0
If you want to keep the same signature of some, you will have to use the reflect package to set the interface{} pointer value:
package main
import (
"fmt"
"reflect"
)
func some(check interface{}) {
val := reflect.ValueOf(check)
if val.Kind() != reflect.Ptr {
panic("some: check must be a pointer")
}
val.Elem().Set(reflect.ValueOf("random"))
}
func main() {
var one interface{}
some(&one)
fmt.Println(one)
}
https://play.golang.org/p/ocqkeLdFLu
Note: val.Elem().Set() will panic if the value passed is not assignable to check's pointed-to type.

How to pass by reference so I can modify it in the calling function?

How can I pass something to a function such that it is modifiable and can be seen in the calling stack ? ( in other words how to pass a pointer or a reference ? )
package main
import (
"os/exec"
"fmt"
)
func process(names *[]string) {
fmt.Print("Pre process", names)
names[1] = "modified"
}
func main() {
names := []string{"leto", "paul", "teg"}
process(&names)
fmt.Print("Post process", names)
}
Error:
invalid operation: names[0] (type *[]string does not support indexing)
Dereferencing a pointer has higher precedence.
Here is a code that works: https://play.golang.org/p/9Bcw_9Uvwl
package main
import (
"fmt"
)
func process(names *[]string) {
fmt.Println("Pre process", *names)
(*names)[1] = "modified"
}
func main() {
names := []string{"leto", "paul", "teg"}
process(&names)
fmt.Println("Post process", names)
}

Go Relflect Declare type struct

I wish I could recover my type of structure and declare a variable of that type .
I tried with Reflect but I can not find the way .
package main
import (
"fmt"
"reflect"
)
type M struct {
Name string
}
func main() {
type S struct {
*M
}
s := S{}
st := reflect.TypeOf(s)
Field, _ := st.FieldByName("M")
Type := Field.Type
test := Type.Elem()
fmt.Print(test)
}
Use reflect.New with your type, here's an example of setting Name on a new instance of M struct using reflection:
package main
import (
"fmt"
"reflect"
)
type M struct {
Name string
}
func main() {
type S struct {
*M
}
s := S{}
mStruct, _ := reflect.TypeOf(s).FieldByName("M")
mInstance := reflect.New(mStruct.Type.Elem())
nameField := mInstance.Elem().FieldByName("Name")
nameField.SetString("test")
fmt.Print(mInstance)
}

go programming language: json marshalling

I'm expecting {"a":"42","b":"78"} from the following code, but it doesn't do it.
package main
import (
"encoding/json"
"fmt"
)
type S struct {
A int `json:"a,string"`
B *int `json:"b,string"`
}
func main() {
var s S
json.Unmarshal([]byte(`{"a":"42","b":"78"}`), &s)
m, _ := json.Marshal(s)
fmt.Println(string(m))
}
Am I doing something wrong?
This is a known issue with 1.3 of the go language.
see https://code.google.com/p/go/issues/detail?id=8587

How to use pointer type in struct initializer?

I cannot figure out how to initialize structure field when it is a reference type alias of the one of the number types:
package main
import (
"fmt"
"encoding/json"
)
type Nint64 *int64
type MyStruct struct {
Value Nint64
}
func main() {
data, _ := json.Marshal(&MyStruct{ Value : ?? 10 ?? })
fmt.Println(string(data))
}
You can't, you will have to add an extra step playground:
func NewMyStruct(i int64) *MyStruct {
return &MyStruct{&i}
}
func main() {
i := int64(10)
data, _ := json.Marshal(&MyStruct{Value: Nint64(&i)})
fmt.Println(string(data))
//or this
data, _ = json.Marshal(NewMyStruct(20))
fmt.Println(string(data))
}
I don't think you want to reference to the address of an int64 ...
package main
import (
"encoding/json"
"fmt"
)
type Nint64 int64
type MyStruct struct {
Value Nint64
}
func main() {
data, _ := json.Marshal(&MyStruct{Value: Nint64(10)})
fmt.Println(string(data))
}
http://play.golang.org/p/xafMLb_c73

Resources