gpt4 book ai didi

json - 我如何说服 UnmarshalJSON 使用 slice 子类型?

转载 作者:IT王子 更新时间:2023-10-29 02:29:19 25 4
gpt4 key购买 nike

我想要使用 base64 在 JSON 中编码和解码的 byte slice RawURLEncoding 而不是 StdEncoding。没有明显的方法可以通过 encoding/json package 来做到这一点,这是明智的,所以我想我会创建一个子类型来做到这一点。

type Thing []byte

编码支持很简单:

func (thing Thing) MarshalJSON() ([]byte, error) {
if thing == nil {
return []byte("null"), nil
}
return []byte(`"` + base64.RawURLEncoding.EncodeToString(thing) + `"`), nil
}

但 Unmarshal 不是那么多。我追踪了 encoding/json source ,并提出:

func (thing Thing) UnmarshalJSON(data []byte) error {
v := reflect.ValueOf(&thing)
if len(data) == 0 || data[0] == 'n' { // null
v.SetBytes([]byte{})
return nil
}
data = data[1 : len(data)-1]
dst := make([]byte, base64.RawURLEncoding.DecodedLen(len(data)))
n, err := base64.RawURLEncoding.Decode(dst, data)
if err != nil {
return err
}
v.SetBytes(Thing(dst[:n]))
return nil
}

但在调用 SetBytes() 时会产生 panic :

panic: reflect: reflect.Value.SetBytes using unaddressable value [recovered]
panic: reflect: reflect.Value.SetBytes using unaddressable value

我尝试使用一个指向 slice 的指针,它可以工作(并且不需要反射),但在我的代码中的其他地方导致了其他挑战,这些挑战希望使用 slice 而不是指针。

我想有两个问题:

  1. 这是使用 RawURLEncoding 获取字节 slice 进行编码的最佳方式吗?
  2. 如果是这样,我如何说服我的字节 slice 子类型引用从 RawURLEncoding 格式解码的数据?

最佳答案

使用此代码解码值:

func (thing *Thing) UnmarshalJSON(data []byte) error {
if len(data) == 0 || data[0] == 'n' { // copied from the Q, can be improved
*thing = nil
return nil
}
data = data[1 : len(data)-1]
dst := make([]byte, base64.RawURLEncoding.DecodedLen(len(data)))
n, err := base64.RawURLEncoding.Decode(dst, data)
if err != nil {
return err
}
*thing = dst[:n]
return nil
}

要点:

  • 使用指针接收器。
  • 不需要反射来将 []byte 分配给事物。

playground example

关于json - 我如何说服 UnmarshalJSON 使用 slice 子类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44125690/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com