>백엔드 개발 >Golang >Go에서 사용자 정의 `MarshalJSON()`을 사용하여 구조체를 관용적으로 포함하는 방법은 무엇입니까?

Go에서 사용자 정의 `MarshalJSON()`을 사용하여 구조체를 관용적으로 포함하는 방법은 무엇입니까?

Patricia Arquette
Patricia Arquette원래의
2024-12-06 13:18:11281검색

How to Idiomatically Embed a Struct with a Custom `MarshalJSON()` in Go?

사용자 정의 MarshalJSON()을 사용하여 구조체를 삽입하기 위한 관용적 방법

내장된 구조체가 사용자 정의된 MarshalJSON() 메서드를 정의할 때 문제가 발생하여 예기치 않은 JSON 직렬화 동작이 발생합니다. 포함된 내용을 마샬링하려고 할 때 struct.

배경

다음 구조체 정의를 고려하세요.

type Person struct {
    Name string `json:"name"`
}

type Employee struct {
    *Person
    JobRole string `json:"jobRole"`
}

Employee 구조체를 예상대로 마샬링하는 것은 간단합니다.

p := Person{"Bob"}
e := Employee{&p, "Sales"}
output, _ := json.Marshal(e)
fmt.Printf("%s\n", string(output))

출력:

{"name":"Bob","jobRole":"Sales"}

문제

그러나 아래와 같이 포함된 구조체에 대해 사용자 정의 MarshalJSON() 메서드를 정의하면 의도한 직렬화가 중단됩니다.

func (p *Person) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct{
        Name string `json:"name"`
    }{
        Name: strings.ToUpper(p.Name),
    })
}

이제 Employee를 마샬링하면 이름 필드가 포함된 출력이 생성됩니다. 대문자로 변환되었지만 jobRole 필드가 누락되었습니다.

{"name":"BOB"}

관용적 해결 방법

원하는 직렬화 동작을 유지하려면 포함된 구조체(Person)에 MarshalJSON() 메서드를 정의하지 마세요. 대신 사용자 정의 마샬링 논리를 캡슐화하는 별도의 유형을 생성하고 해당 유형을 포함합니다.

type Name string

func (n Name) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct{
        Name string `json:"name"`
    }{
        Name: strings.ToUpper(string(n)),
    })
}

type Person struct {
    Name Name `json:"name"`
}

이 접근 방식은 마샬링 사용자 정의를 전용 유형으로 격리하여 Person 구조체를 다른 곳에 포함할 때 예상치 못한 부작용을 방지합니다.

예: https://play.golang.org/p/u96T4C6PaY

위 내용은 Go에서 사용자 정의 `MarshalJSON()`을 사용하여 구조체를 관용적으로 포함하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.