programing

golang json marshal: 빈 중첩 구조를 생략하는 방법

javajsp 2023. 3. 25. 09:54

golang json marshal: 빈 중첩 구조를 생략하는 방법

운동장에 가다

위의 코드와 같이, 다음과 같이 사용할 수 있습니다.json:",omitempty"구조체의 특정 필드를 생략하여 json으로 표시합니다.

예를들면

type ColorGroup struct {
    ID     int `json:",omitempty"`
    Name   string
    Colors []string
}
type Total struct {
    A ColorGroup`json:",omitempty"`
    B string`json:",omitempty"`
}
group := Total{
       A: ColorGroup{},

}

이 경우,B에 나타나지 않다json.Marshal(group)

단, 만약

group := Total{
       B:"abc",

}

A에 아직 나타나다json.Marshal(group)

{"A":{"Name":"","Colors":null},"B":"abc"}

문제는 어떻게 우리가 오직

{"B":"abc"}

편집: 구글 검색 후 제안 사용 포인터가 있습니다. 즉,Total안으로

type Total struct {
    A *ColorGroup`json:",omitempty"`
    B string`json:",omitempty"`
}

매뉴얼에서 다음 항목을 참조하십시오.

구조값은 JSON 개체로 인코딩됩니다.내보낸 각 구조 필드는 다음과 같은 경우를 제외하고 객체의 멤버가 됩니다.

  • 필드의 태그는 "-" 또는
  • 필드가 비어 있고 태그가 "빈" 옵션을 지정합니다.

빈 값은 false, 0, 제로 포인터 또는 인터페이스 값 및 길이0의 배열, 슬라이스, 맵 또는 문자열입니다.

귀하의 선언에 따르면group은 함축되어 있습니다.group.A의 제로값이 됩니다.ColorGroup구조 유형.또한 "빈 값"으로 간주되는 항목 목록에는 구조 유형의 값 0이 언급되지 않습니다.

찾으셨듯이, 이 경우의 회피책은 포인터를 사용하는 것입니다.지정하지 않으면 동작합니다.A에 대한 당신의 선언으로group. 제로 구조의 포인터로 지정하면 다시 표시됩니다.

놀이터 링크:

package main

import (
    "encoding/json"
    "fmt"
    "os"
)

func main() {
    type colorGroup struct {
        ID     int `json:",omitempty"`
        Name   string
        Colors []string
    }
    type total struct {
        A *colorGroup `json:",omitempty"`
        B string     `json:",omitempty"`
    }

    groupWithNilA := total{
        B: "abc",
    }
    b, err := json.Marshal(groupWithNilA)
    if err != nil {
        fmt.Println("error:", err)
    }
    os.Stderr.Write(b)

    println()

    groupWithPointerToZeroA := total{
        A: &colorGroup{},
        B: "abc",
    }
    b, err = json.Marshal(groupWithPointerToZeroA)
    if err != nil {
        fmt.Println("error:", err)
    }
    os.Stderr.Write(b)
}

구조물에 대한 포인터를 사용하지 않으려면 이 방법을 대신할 수 있습니다.Container구조 용구json.Marshaller스트컷의 멤버를 생략할 수 있습니다.

https://play.golang.com/p/hMJbQ-QQ5PU

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    for _, c := range []Container{
        {},
        {
            Element: KeyValue{
                Key:   "foo",
                Value: "bar",
            },
        },
    } {
        b, err := json.Marshal(c)
        if err != nil {
            panic(err)
        }
        fmt.Println(string(b))
    }
}

type Container struct {
    Element KeyValue
}

func (c Container) MarshalJSON() ([]byte, error) {
    // Alias is an alias type of Container to avoid recursion.
    type Alias Container

    // AliasWithInterface wraps Alias and overrides the struct members,
    // which we want to omit if they are the zero value of the type.
    type AliasWithInterface struct {
        Alias
        Element interface{} `json:",omitempty"`
    }

    return json.Marshal(AliasWithInterface{
        Alias:   Alias(c),
        Element: c.Element.jsonValue(),
    })
}

type KeyValue struct {
    Key   string
    Value string
}

// jsonValue returns nil if kv is the zero value of KeyValue. It returns kv otherwise.
func (kv KeyValue) jsonValue() interface{} {
    var zero KeyValue
    if kv == zero {
        return nil
    }
    return kv
}

편집: 문서 추가

쉬운 방법

type <name> struct {
< varname > < vartype > \`json : -\`
}

예:

type Boy struct {
name string \`json : -\`
}

집결할 때 이쪽name는 시리얼화되지 않습니다.

언급URL : https://stackoverflow.com/questions/33447334/golang-json-marshal-how-to-omit-empty-nested-struct