How to Initialize Values for Nested Struct Array in Golang
My Struct Type Result Struct { Name String Objects []Struct { Id Int } } Initialize Values for This Func Main() { Var R Result; R. Name = "Vanaraj"; R...
My struct
type Result struct {
name string
Objects []struct {
id int
}
}
Initialize values for this
func main() {
var r Result;
r.name = "Vanaraj";
r.Objects[0].id = 10;
fmt.Println(r)
}
I got this error. "panic: runtime error: index out of range"
How to fix this?
4 Answers
Firstly, I'd say it's more idiomatic to define a type for your struct, regardless of how simple the struct is. For example:
type MyStruct struct {
MyField int
}
This would mean changing your Result struct to be as follows:
type Result struct {
name string
Objects []MyStruct
}
The reason your program panics is because you're trying to access an area in memory (an item in your Objects array) that hasn't been allocated yet.
For arrays of structs, this needs to be done with make.
r.Objects = make([]MyStruct, 0)
Then, in order to add to your array safely, you're better off instantiating an individual MyStruct, i.e.
ms := MyStruct{
MyField: 10,
}
And then appending this to your r.Objects array
r.Objects = append(r.Objects, ms)
For more information about make, see the docs
After defining the struct as suggested in another answer:
type MyStruct struct {
MyField int
}
type Result struct {
Name string
Objects []MyStruct
}
Then you can initialize a Result object like this:
result := Result{
Name: "I am Groot",
Objects: []MyStruct{
{
MyField: 1,
},
{
MyField: 2,
},
{
MyField: 3,
},
},
}
Full code:
package main
import "fmt"
func main() {
result := Result{
Name: "I am Groot",
Objects: []MyStruct{
{
MyField: 1,
},
{
MyField: 2,
},
{
MyField: 3,
},
},
}
fmt.Println(result)
}
type MyStruct struct {
MyField int
}
type Result struct {
Name string
Objects []MyStruct
}
You can verify this in this Go playground.
Objects contains no elements. You need to append element first. Like this:
r.Objects = append(r.Objects, struct{ id int }{})
Also you can omit r.Objects[0].id = 10; using initialization of your struct like this:
r.Objects = append(r.Objects, struct{ id int }{ 10 })
This is probably a dumb idea, but you can roundtrip it through JSON:
package main
import (
"bytes"
"encoding/json"
)
type (
a []interface{}
m map[string]interface{}
)
func decode(in, out interface{}) {
var b bytes.Buffer
json.NewEncoder(&b).Encode(in)
json.NewDecoder(&b).Decode(out)
}
Example:
package main
import "fmt"
type result struct {
Name string
Objects []struct {
Id int
}
}
func main() {
r := m{
"Name": "Vanaraj",
"Objects": a{
m{"Id": 10},
},
}
var s result
decode(r, &s)
fmt.Printf("%+v\n", s) // {Name:Vanaraj Objects:[{Id:10}]}
}