>백엔드 개발 >Golang >UnmarshalJSON 내에서 json.Unmarshal을 사용할 때 스택 오버플로를 방지하는 방법은 무엇입니까?

UnmarshalJSON 내에서 json.Unmarshal을 사용할 때 스택 오버플로를 방지하는 방법은 무엇입니까?

Barbara Streisand
Barbara Streisand원래의
2024-12-19 22:50:15124검색

How to Avoid Stack Overflow When Using json.Unmarshal Inside UnmarshalJSON?

스택 오버플로 없이 UnmarshalJSON 함수 내에서 json.Unmarshal 호출

사용자 정의 UnmarshalJSON 구현에서 json.Unmarshal(b, type)을 호출하면 다음이 발생할 수 있습니다. 오버플로를 스택합니다. 이는 JSON 디코더가 사용자 정의 UnmarshalJSON 구현을 반복적으로 확인하여 끝없는 재귀가 발생하기 때문에 발생합니다.

이 문제를 방지하려면 type 키워드를 사용하여 새 유형을 생성하고 유형 변환을 사용하여 원래 값을 할당하세요. 이는 새 유형이 기본 유형으로 원본 유형을 갖기 때문에 가능합니다.

예:

Age 필드가 있는 Person 유형이 있다고 가정합니다. Age가 음수일 수 없도록 하기 위해 다음과 같이 UnmarshalJSON을 구현할 수 있습니다.

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

func (p *Person) UnmarshalJSON(data []byte) error {
    type person2 Person
    if err := json.Unmarshal(data, (*person2)(p)); err != nil {
        return err
    }

    // Post-processing after unmarshaling:
    if p.Age < 0 {
        p.Age = 0
    }
    return nil
}

이 접근 방식에서 person2 유형은 메서드가 없는 새 유형을 생성하여 재귀를 방지합니다. 데이터가 정렬 해제되면 person2 유형에 할당된 다음 원래 Person 유형에 할당되어 사후 처리가 가능해집니다.

테스트:

import (
    "encoding/json"
    "fmt"
)

func main() {
    var p *Person
    fmt.Println(json.Unmarshal([]byte(`{"name":"Bob","age":10}`), &p))
    fmt.Println(p)

    fmt.Println(json.Unmarshal([]byte(`{"name":"Bob","age":-1}`), &p))
    fmt.Println(p)
}

출력:

<nil>
&{Bob 10}
<nil>
&{Bob 0}

이는 사용자 정의 방법을 보여줍니다. 스택 오버플로를 일으키지 않고 JSON을 비정렬화합니다.

위 내용은 UnmarshalJSON 내에서 json.Unmarshal을 사용할 때 스택 오버플로를 방지하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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