The simple answer: Your program crashes due to infinite recursion.
You called json.Marshal(o) , which will look like MarshalJSON() in your methods, but, unfortunately, you also called json.Marshal(o) in MarshalJSON() , which ultimately leads to endless recursion of the causes and use of system of memory
It is called a general newbie mistake , because your code will lead to infinite recursion.
Here is a simpler version of your code using String()
Other recursion Example:
package main import "fmt" type A int func (a A) String() string { return fmt.Sprintf("%v", a) } func main() { var a A fmt.Println("this will never print", a) }
That's why go is trying to impose a stack size limit as a workaround
2 Simple Solutions
- Use a different name
- Do not return
return json.Marshal(o) , but Item
Solution 1 Example
package main import ( "encoding/json" "fmt" "sync" ) type Object struct { Name string Value int sync.RWMutex } func (o *Object) ParseJSON() ([]byte, error) { o.RLock() defer o.RUnlock() fmt.Println("Marshalling object") return json.Marshal(o) } func main() { o := &Object{Name: "ANisus", Value: 42} j, err := o.ParseJSON() // THis would work if err != nil { panic(err) } fmt.Printf("%s\n", j) j, err = json.Marshal(o) // this would work if err != nil { panic(err) } fmt.Printf("%s\n", j) }
Live demo
Solution 2 Example
main package
import ( "encoding/json" "fmt" "sync" ) type Item struct { Name string Value int } type Object struct { item Item sync.RWMutex } func (o *Object) MarshalJSON() ([]byte, error) { o.RLock() defer o.RUnlock() fmt.Println("Marshalling object") return json.Marshal(o.item) } func main() { o := &Object{item : Item{Name: "ANisus", Value: 42}} j, err := json.Marshal(o) if err != nil { panic(err) } fmt.Printf("%s\n", j) }
Live demo
source share