在 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中文网其他相关文章!