In your sample code data should be JSON-encoded (in simple word String) so you are using Unmarshal in a wrong way:
// Unmarshal parses the JSON-encoded data and stores the result // in the value pointed to by v. If v is nil or not a pointer, // Unmarshal returns an InvalidUnmarshalError. func Unmarshal(data []byte, v interface{}) error
Try it on The Go Playground and this: []string{"art", "football"}:
package main
import (
"encoding/json"
"fmt"
)
func main() {
// ********************* Marshal *********************
u := map[string]interface{}{}
u["name"] = "kish"
u["age"] = 28
u["work"] = "engine"
//u["hobbies"] = []string{"art", "football"}
u["hobbies"] = "art"
b, err := json.Marshal(u)
if err != nil {
panic(err)
}
fmt.Println(string(b))
// ********************* Unmarshal *********************
var a interface{}
err = json.Unmarshal(b, &a)
if err != nil {
fmt.Println("error:", err)
}
fmt.Println(a)
}
output:
{"age":28,"hobbies":"art","name":"kish","work":"engine"}
map[name:kish work:engine age:28 hobbies:art]
You want to Unmarshal it, so try this simple working example ([]byte(kpi.(string))):
package main
import (
"encoding/json"
"fmt"
)
func main() {
var kpi interface{} = st
var a []Animal
err := json.Unmarshal([]byte(kpi.(string)), &a)
if err != nil {
fmt.Println("error:", err)
}
fmt.Println(a)
}
type Animal struct {
Name string
Order string
}
var st = `[
{"Name": "Platypus", "Order": "Monotremata"},
{"Name": "Quoll", "Order": "Dasyuromorphia"}
]`
output:
[{Platypus Monotremata} {Quoll Dasyuromorphia}]
Working example using ([]byte(*kpi.(*string))):
package main
import (
"encoding/json"
"fmt"
)
func main() {
var kpi interface{} = &st
var a []Animal
err := json.Unmarshal([]byte(*kpi.(*string)), &a)
if err != nil {
fmt.Println("error:", err)
}
fmt.Println(a)
}
type Animal struct {
Name string
Order string
}
var st = `[
{"Name": "Platypus", "Order": "Monotremata"},
{"Name": "Quoll", "Order": "Dasyuromorphia"}
]`
Marshal:
package main
import (
"encoding/json"
"fmt"
)
func main() {
u := map[string]interface{}{}
u["1"] = "one"
b, err := json.Marshal(u)
if err != nil {
panic(err)
}
fmt.Println(string(b))
}
output:
{"1":"one"}
I hope this helps.
Answer from wasmup on Stack OverflowIn your sample code data should be JSON-encoded (in simple word String) so you are using Unmarshal in a wrong way:
// Unmarshal parses the JSON-encoded data and stores the result // in the value pointed to by v. If v is nil or not a pointer, // Unmarshal returns an InvalidUnmarshalError. func Unmarshal(data []byte, v interface{}) error
Try it on The Go Playground and this: []string{"art", "football"}:
package main
import (
"encoding/json"
"fmt"
)
func main() {
// ********************* Marshal *********************
u := map[string]interface{}{}
u["name"] = "kish"
u["age"] = 28
u["work"] = "engine"
//u["hobbies"] = []string{"art", "football"}
u["hobbies"] = "art"
b, err := json.Marshal(u)
if err != nil {
panic(err)
}
fmt.Println(string(b))
// ********************* Unmarshal *********************
var a interface{}
err = json.Unmarshal(b, &a)
if err != nil {
fmt.Println("error:", err)
}
fmt.Println(a)
}
output:
{"age":28,"hobbies":"art","name":"kish","work":"engine"}
map[name:kish work:engine age:28 hobbies:art]
You want to Unmarshal it, so try this simple working example ([]byte(kpi.(string))):
package main
import (
"encoding/json"
"fmt"
)
func main() {
var kpi interface{} = st
var a []Animal
err := json.Unmarshal([]byte(kpi.(string)), &a)
if err != nil {
fmt.Println("error:", err)
}
fmt.Println(a)
}
type Animal struct {
Name string
Order string
}
var st = `[
{"Name": "Platypus", "Order": "Monotremata"},
{"Name": "Quoll", "Order": "Dasyuromorphia"}
]`
output:
[{Platypus Monotremata} {Quoll Dasyuromorphia}]
Working example using ([]byte(*kpi.(*string))):
package main
import (
"encoding/json"
"fmt"
)
func main() {
var kpi interface{} = &st
var a []Animal
err := json.Unmarshal([]byte(*kpi.(*string)), &a)
if err != nil {
fmt.Println("error:", err)
}
fmt.Println(a)
}
type Animal struct {
Name string
Order string
}
var st = `[
{"Name": "Platypus", "Order": "Monotremata"},
{"Name": "Quoll", "Order": "Dasyuromorphia"}
]`
Marshal:
package main
import (
"encoding/json"
"fmt"
)
func main() {
u := map[string]interface{}{}
u["1"] = "one"
b, err := json.Marshal(u)
if err != nil {
panic(err)
}
fmt.Println(string(b))
}
output:
{"1":"one"}
I hope this helps.
Working example based on the one provided by Kugel:
package main
import (
"fmt"
)
func passInterface(v interface{}) {
b, ok := v.(*[]byte)
fmt.Println(ok)
fmt.Println(b)
}
func main() {
passInterface(&[]byte{0x00, 0x01, 0x02})
}
Play
If you do not pass references, it will work basically the same:
Play
go - Convert arbitrary Golang interface to byte array - Stack Overflow
Use Bytes() instead of Interface().([]byte) for reflect.Slice marshalling
Use []T as []interface{}
go - How to convert interface{} to bytes.Buffer - Stack Overflow
When you unmarshall JSON into interface{}, it has no way to know what type you want it to use, so it defaults to map[string]interface{} as indicated in the documentation:
To unmarshal JSON into an interface value, Unmarshal stores one of these in the interface value:
...
map[string]interface{}, for JSON objects
If you want to unmarshal to a specific type, pass an instance of that type to Unmarshal:
var result sample
err = json.Unmarshal(data,&result)
You can not unmarshal to nil interface, however, if interface has a pointer to undelying structure it will work see below your updated code:
package main
import (
"encoding/json"
"fmt"
"github.com/viant/toolbox"
"log"
)
type sample struct {
Ping string `json:"ping"`
Pong sample1 `json:"long"`
}
type sample1 struct {
Play string `json:"plong"`
}
func main() {
var ans sample
var result interface{} = &sample{}
ans.Ping = "asda"
var ans1 sample1
ans1.Play = "asasd"
ans.Pong = ans1
fmt.Println(ans)
converter := toolbox.NewColumnConverter(toolbox.DefaultDateLayout)
var aMap = make(map[string]interface{})
converter.AssignConverted(&aMap, ans)
data, err := json.Marshal(ans)
fmt.Println(err)
fmt.Println(string(data), err)
err = json.Unmarshal(data,&result)
fmt.Println(result)
if err!= nil{
log.Fatal(err)
}
fmt.Println(result.(*sample))
fmt.Println(result)
}
Other problems in my code led me away from the gob package earlier, turns out it was the proper way as @nvcnvn suggested. Relevant code on how to solve this issue below:
package bloom
import (
"encoding/gob"
"bytes"
)
func GetBytes(key interface{}) ([]byte, error) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
err := enc.Encode(key)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
Another way to convert interface{} to []bytes is to use a fmt package.
/*
* Convert variable `key` from interface{} to []byte
*/
byteKey := []byte(fmt.Sprintf("%v", key.(interface{})))
fmt.Sprintf converts interface value to string.
[]byte converts string value to byte.
※ Note ※ This method does not work if interface{} value is a pointer. Please find @PassKit's comment below.