Go에서 양방향 목록을 JSON으로 변환 할 때 비틀림
무엇이 있었는지
Go로 코딩하는 동안, 양방향 리스트 같은 것을 자작&JSON으로 변환할 필요성이 있었다. 정책으로서는 encoding/json
를 사용해 몇 가지 생각이, 엉망이 막혀 버렸다, 라고 하는 이야기.
요컨대
json:"-"
에서 무시하고 차단하십시오 struct에 자신이 있으면 invalid recursive type
당연히 당연한 이야기입니다만.
실패편
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
# command-line-arguments
./main.go:9:6: invalid recursive type Person
그럼 그렇다고 하는 느낌. 상호 재귀에서도 화내는 것 같습니다. 우수.
성공편
포인터로 고쳐 해결.
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}
JSON 순환 차단
본제입니다.
원래 양방향 목록을 JSON으로 바꾸고 싶은 것이 얼마나 있는지 궁금합니다.
Person
의 구조는 이전과 동일합니다. 이런 느낌에 작은 양방향 목록을 결합합니다.
실패편
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))
}
출력은 이런 느낌으로 말 그대로 무한히 화나게 됩니다. 재귀 오류입니다.
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
그건 당연합니다. "Parent에 JSON 태그를 붙이지 않으면 원찬 무시해 주지 않을까?"라는 얕은 생각을 한 것이 안된다. 디폴트로 필드명을 그대로 사용해 변환해 줍니다. 매우 우수한 라이브러리.
성공편
즉 내가 하고 싶은 것은 「JSON 라이브러리로 임의의 필드를 무시한다」라고 하는 것.
이렇게 하려면 태그를 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))
}
출력 결과는 이쪽. 제대로 Child만 가지고 있어요. Root에서 당긴다면 Parent는 따로 낼 필요 없으니까요.
$ go run main.go
[{"name":"Momo Asakura","child":{"name":"Shiina Natsukawa","child":null}},{"name":"Shiina Natsukawa","chil
d":null}]
요약
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
# command-line-arguments
./main.go:9:6: invalid recursive type Person
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}
본제입니다.
원래 양방향 목록을 JSON으로 바꾸고 싶은 것이 얼마나 있는지 궁금합니다.
Person
의 구조는 이전과 동일합니다. 이런 느낌에 작은 양방향 목록을 결합합니다.실패편
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))
}
출력은 이런 느낌으로 말 그대로 무한히 화나게 됩니다. 재귀 오류입니다.
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
그건 당연합니다. "Parent에 JSON 태그를 붙이지 않으면 원찬 무시해 주지 않을까?"라는 얕은 생각을 한 것이 안된다. 디폴트로 필드명을 그대로 사용해 변환해 줍니다. 매우 우수한 라이브러리.
성공편
즉 내가 하고 싶은 것은 「JSON 라이브러리로 임의의 필드를 무시한다」라고 하는 것.
이렇게 하려면 태그를
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))
}
출력 결과는 이쪽. 제대로 Child만 가지고 있어요. Root에서 당긴다면 Parent는 따로 낼 필요 없으니까요.
$ go run main.go
[{"name":"Momo Asakura","child":{"name":"Shiina Natsukawa","child":null}},{"name":"Shiina Natsukawa","chil
d":null}]
요약
Reference
이 문제에 관하여(Go에서 양방향 목록을 JSON으로 변환 할 때 비틀림), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/pgDora56/items/c2a9de7b9852d5bab042텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)