首页 > 解决方案 > 如何在 UnmarshalJSON 中调用 json.Unmarshal 而不会导致堆栈溢出?

问题描述

如何在结构中创建方法 UnmarshalJSON,在内部使用 json.Unmarshal 而不会导致堆栈溢出?

package xapo

type Xapo struct {}

func (x Xapo) UnmarshalJSON(data []byte) error {
    err := json.Unmarshal(data, &x)
    if err != nil {
        return err
    }
    fmt.Println("done!")
    return nil
}

有人能解释一下为什么会发生堆栈溢出吗?可以修复吗?

提前致谢。

标签: gostruct

解决方案


看起来您可能正在尝试通过使用默认解组器然后对数据进行后处理来进行自定义解组。但是,正如您所发现的,尝试这样做的明显方法会导致无限循环!

通常的解决方法是使用您的类型创建一个新类型,在新类型的实例上使用默认解组器,对数据进行后处理,然后最终转换为原始类型并分配回目标实例。请注意,您需要在指针类型上实现 UnmarshalJSON。

例如:

func (x *Xapo) UnmarshalJSON(data []byte) error {
  // Create a new type from the target type to avoid recursion.
  type Xapo2 Xapo

  // Unmarshal into an instance of the new type.
  var x2 Xapo2
  err := json.Unmarshal(data, &x2)
  if err != nil {
    return err
  }

  // Perform post-processing here.
  // TODO

  // Cast the new type instance to the original type and assign.
  *x = Xapo(x2)
  return nil
}

推荐阅读