首页 > 后端开发 > Golang > 在 UnmarshalJSON 中使用 json.Unmarshal 时如何避免堆栈溢出?

在 UnmarshalJSON 中使用 json.Unmarshal 时如何避免堆栈溢出?

Barbara Streisand
发布: 2024-12-19 22:50:15
原创
115 人浏览过

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}
登录后复制

这演示了如何自定义 UnmarshalJSON不会导致堆栈溢出。

以上是在 UnmarshalJSON 中使用 json.Unmarshal 时如何避免堆栈溢出?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板