【问题标题】:Is it safe to assume that json.Marshall on a particular struct can not possibly fail?假设特定结构上的 json.Marshall 不可能失败是否安全?
【发布时间】:2017-10-30 06:16:58
【问题描述】:

我已阅读this question,它询问 json.Marshal 是否会因任何输入而失败,并且根据我的情况看起来它不会失败的答案。我的情况如下:

我有一个特定的结构(没有嵌套,没有数组,只有字符串,各种类型的整数,布尔值)。我需要将其编组为 json。它会失败吗?

在更多specific example

type some struct {
    F1 string `json:"f1"`
    F2 uint32 `json:"f2"`
    F3 int64  `json:"f3"`
    F4 bool   `json:"f4"`
}

func doSomething(s some) (string, error) {
    data, err := json.Marshal(s)
    if err != nil {
        return "", err
    }
    return string(data), nil
}

doSomething 会失败吗?如果是,请提供输入,否则解释原因。根据我目前的知识,它不能。

【问题讨论】:

  • 如果一个函数(例如json.Marshal)返回一个错误值,永远不要假设它不会失败,除非文档明确说明。它返回一个错误是有原因的。
  • @Adrian 你错过了这个问题的重点。关键是要弄清楚它为什么会失败。所以对我来说,如果你在文档中看到一些你看不到原因的东西,请询问其他人并学习新的东西
  • 你误解了评论的意思,它在接受的答案中得到了回应:函数返回一个错误值,文档并没有说它总是为零,所以它可能会返回一个错误,并且它可能返回错误的情况可能因 Go 版本而异。如果你想知道在特定的 Go 版本下它何时可能返回错误,请阅读该版本中的函数源。

标签: go


【解决方案1】:

我可以在这里看到三个潜在的错误来源:

  1. 字符串和各种 UTF8 东西

  2. int64。 JSON 中的数字通常被视为 float64,因此对于绝对值大于 2^53 的数字,迂腐的实现可能会返回错误,因为它们可能很危险。

  3. 反映。

1 和 2 目前不会发生(encoding/json 中的函数不会返回错误或恐慌)。我还没有深入研究 reflect 的代码来验证 3,但这是那些微不足道的可测试案例之一。它要么在第一次尝试时失败,要么总是有效。

另一方面。过去,如果字符串包含无效的 UTF8 字符,json 编码器会返回错误。它不再那样做,但这指出了一个重要的原则——事情会发生变化。仅仅因为今天没有返回某个错误并不意味着将来不会有错误。该函数被定义为返回错误。这意味着标准库开发人员在未来开始为今天可能不是错误的事情返回新错误是完全有效的。所以答案是——是的,它可能会失败。也许不是今天,但依赖于特定标准库版本的代码是糟糕的代码。

【讨论】:

  • 非常感谢int64。我不完全同意“函数被定义为返回错误。这意味着标准库开发人员开始返回新错误是完全有效的”,因为函数可以返回在接口上操作的错误。这并不意味着它可以在某些特定示例上返回错误。但无论如何,非常感谢您的回答。
  • @SalvadorDali 如果我设计了 encoding/json,我会让它在你的示例结构的一些可能值上失败。我喜欢我的编码器和解码器是可逆的,如果我不能保证x == decode(encode(x)) 我会返回一个错误。 encoding/json 不保证今天不会返回错误,但我不明白为什么有人不会在未来改变主意,这不是一个很有争议的原则。
猜你喜欢
  • 2016-12-13
  • 2011-09-28
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 1970-01-01
  • 2011-02-27
  • 2020-07-01
  • 1970-01-01
相关资源
最近更新 更多