While coding with Go, I had to convert something like a bidirectional list to my own & JSON. The policy is to use ʻencoding / json`, but it's a mess.
json:"-"
and stop itIt's a matter of course.
package main
import (
"encoding/json"
"fmt"
"log"
)
type Person struct {
Name string
Parent Person
Child Person
}
func main() {
sora := Person{}
sora.Name = "Sora Amamiya"
j, err := json.Marshal(sora)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(j))
}
I get angry like this.
$ go run main.go
# command-line-arguments
./main.go:9:6: invalid recursive type Person
That's right. It seems that they get angry even with mutual recursion. excellence.
Solved by fixing it to a pointer.
package main
import (
"encoding/json"
"fmt"
"log"
)
type Person struct {
Name string
Parent *Person
Child *Person
}
func main() {
sora := Person{}
sora.Name = "Sora Amamiya"
j, err := json.Marshal(sora)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(j))
}
$ go run main.go
{"Name":"Sora Amamiya","Parent":null,"Child":null}
This is the main subject. I'm wondering how often I want to turn a bidirectional list into JSON in the first place.
The structure of Person
is the same as before. Make a small bidirectional list like this.
package main
import (
"encoding/json"
"fmt"
"log"
)
type Person struct {
Name string `json:"name"`
Parent *Person
Child *Person `json:"child"`
}
func main() {
m := Person{}
n := Person{}
m.Name = "Momo Asakura"
m.Child = &n
n.Name = "Shiina Natsukawa"
n.Parent = &m
j, err := json.Marshal([]Person{m, n})
if err != nil {
log.Fatal(err)
}
fmt.Println(string(j))
}
The output is literally endlessly angry like this. It's a recursive error.
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow
runtime stack:
runtime.throw(0x4f30b2, 0xe)
/usr/local/go/src/runtime/panic.go:774 +0x72
runtime.newstack()
/usr/local/go/src/runtime/stack.go:1046 +0x6e9
runtime.morestack()
/usr/local/go/src/runtime/asm_amd64.s:449 +0x8f
goroutine 1 [running]:
encoding/json.stringEncoder(0xc00007c000, 0x4c8f80, 0xc00000c080, 0x198, 0x100)
/usr/local/go/src/encoding/json/encode.go:589 +0x389 fp=0xc02009a380 sp=0xc02009a378 pc=0x4a94c9
encoding/json.structEncoder.encode(0xc000082000, 0x3, 0x4, 0xc00005e2a0, 0xc00007c000, 0x4dcee0, 0xc00000c
That's quite natural. It's no good to have a shallow idea, "If you don't attach a JSON tag to Parent, can you ignore Wanchan?" By default, the field name is used as it is and converted. A very good library.
So what I wanted to do was "ignore arbitrary fields in the JSON library".
To do this, use the tag json:"-"
.
package main
import (
"encoding/json"
"fmt"
"log"
)
type Person struct {
Name string `json:"name"`
Parent *Person `json:"-"`
Child *Person `json:"child"`
}
func main() {
m := Person{}
n := Person{}
m.Name = "Momo Asakura"
m.Child = &n
n.Name = "Shiina Natsukawa"
n.Parent = &m
j, err := json.Marshal([]Person{m, n})
if err != nil {
log.Fatal(err)
}
fmt.Println(string(j))
}
Click here for the output result. He brings only Child properly. If you pull from Root, you don't need to put out Parent separately.
$ go run main.go
[{"name":"Momo Asakura","child":{"name":"Shiina Natsukawa","child":null}},{"name":"Shiina Natsukawa","chil
d":null}]
Recommended Posts