You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言readJSON函数单JSON校验逻辑的两处技术疑问

关于Go语言readJSON函数的两个疑问

先看这段代码:

func (app *Config) readJSON(w http.ResponseWriter, r http.Request, data any) error {
    maxBytes := 1048576
    r.Body = http.MaxBytesReader(w, r.Body, int64(maxBytes))
    dec := json.NewDecoder(r.Body)
    err := dec.Decode(data)
    if err != nil {
        return err
    }

    err = dec.Decode(&struct{}{})
    if err != io.EOF {
        return errors.New("Body must have only a single JSON body")
    }

    return nil
}

针对err = dec.Decode(&struct{}{})这一行,有两个疑问:

1. 为何要传入&struct{}{}到Decode函数中,以此校验请求仅包含单个JSON体?

json.Decoder的Decode方法会从输入流里读取下一个JSON值。第一次调用dec.Decode(data)已经把请求中的JSON数据解析到传入的data变量里,但如果请求体里还存在额外的JSON内容(比如连续两个独立的JSON对象),输入流并没有被读完。

这时候调用第二次Decode,传入&struct{}{}(空结构体指针)的原因是:空结构体可以匹配任何JSON对象/值(它没有需要绑定的字段,解析时会忽略所有JSON内容),这样不管剩余的JSON是什么格式,Decode都能尝试读取。如果第二次Decode返回io.EOF,说明第一次Decode已经读完整个请求体,也就是只有单个JSON体;如果返回的不是io.EOF,就意味着请求体里还有未读取的JSON数据,说明存在多个JSON体,此时返回错误提示。

2. 此处为何使用赋值运算符=而非短变量声明:=?

因为err变量已经在前面的err := dec.Decode(data)行被声明过了。如果这里用:=,会在当前代码块重新声明一个新的局部err变量,这个新变量的作用域只限于这一行之后的代码(也就是后续的if判断块),而我们需要复用之前已经声明好的err变量来接收第二次Decode的结果,所以必须用赋值运算符=,而非短变量声明:=。

内容的提问来源于stack exchange,提问作者user63898

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:22:53