Golang中json.Compact函数会验证JSON但文档未提及
Golang中json.Compact函数会验证JSON但文档未提及
json.Compact 的文档非常简洁:
// Compact 将去除无关空格的 JSON 编码 src 追加到 dst。
阅读相关代码部分后,我发现 Compact 不仅压缩 JSON,还会验证 JSON。在调用 json.Compact 之后再调用 json.Valid 是多余的。我认为文档应该明确说明这一点。
以下是相关代码部分: https://go.googlesource.com/go/+/go1.16.2/src/encoding/json/indent.go#17 https://go.googlesource.com/go/+/go1.16.2/src/encoding/json/scanner.go#30
以下是我对文档修改的建议:
// Compact 将去除无关空格的 JSON 编码 src 追加到 dst。Compact 同时会验证 JSON 编码。
大家觉得如何?
更多关于Golang中json.Compact函数会验证JSON但文档未提及的实战教程也可以访问 https://www.itying.com/category-94-b0.html
Compact 不会调用 Valid 或 checkvalid,但它们是等效的。
Valid 通过在 checkValid 中调用 scan.step 来检查编码是否有效。Compact 也是如此。
func main() {
fmt.Println("hello world")
}
我能想到的唯一未被接受的原因是,如果 json.Compact 不能保证进行验证。如果 Go 的参考实现进行了验证,那固然很好,但如果他们将其添加到文档中,那就意味着其他替代实现也必须进行验证。
func main() {
fmt.Println("hello world")
}
由于 Compact 函数会返回一个错误,我认为它隐含了输入必须是有效的 JSON。如果能将这个保证明确地记录在文档中,那就更好了。
感谢 petrus 的反馈,我认为文档应该这样写:
// Compact 将去除空白字符后的 JSON 编码 src 追加到 dst 中。
// 如果 src 不是有效的 JSON,则不会追加 src 并返回一个非 nil 的错误。
zamicol:
json.Compact 的文档很简洁
文档是清晰的。
json 包实现了 RFC 7159 中定义的 JSON 编码和解码。
func Compact(dst *bytes.Buffer, src []byte) error
Compact 将去除无关空格的 JSON 编码的 src 追加到 dst。
Compact 追加的是 JSON 编码的 src,其中 JSON 编码的定义遵循 RFC 7159。如果 src 不是 JSON 编码的,则 src 不会被追加,并且会返回一个非 nil 的错误。
dst 可以是 JSON 编码的,也可以不是。
我同意你的观点,特别是文档即契约这一点。这也是我对在文档中说明该函数会执行验证的担忧。然而,我认为让函数的功能含糊不清也是不可取的。
问题依然存在:如果不是因为无效的 JSON,error 又是什么呢?
因此,或许更好的文档说明是:“对于此 Compact 实现,如果 src 不是有效的 JSON,则不会追加 src 并返回非 nil 错误。” 或者,“未来版本的 Compact 可能不提供此保证。” 我认为后者是我的偏好。
所以,这是我更新的提案:
// Compact appends to dst the JSON-encoded src with insignificant space
// characters elided. If src is not valid JSON, src is not appended and a non-nil
// error is returned. Future versions Compact may not have this guarantee.
是的,你的观察是正确的。json.Compact 函数确实会在压缩过程中验证 JSON 的有效性。如果传入无效的 JSON,它会返回一个错误。因此,在调用 json.Compact 后再次调用 json.Valid 确实是多余的。
以下是一个示例代码,演示了 json.Compact 的验证行为:
package main
import (
"bytes"
"encoding/json"
"fmt"
)
func main() {
// 有效的 JSON
validJSON := []byte(`{"name": "Alice", "age": 30}`)
// 无效的 JSON(缺少闭合括号)
invalidJSON := []byte(`{"name": "Bob", "age": 25`)
var buf bytes.Buffer
// 压缩有效 JSON
err := json.Compact(&buf, validJSON)
if err != nil {
fmt.Printf("有效 JSON 压缩错误: %v\n", err)
} else {
fmt.Printf("压缩结果: %s\n", buf.String())
}
buf.Reset()
// 压缩无效 JSON
err = json.Compact(&buf, invalidJSON)
if err != nil {
fmt.Printf("无效 JSON 压缩错误: %v\n", err)
} else {
fmt.Printf("压缩结果: %s\n", buf.String())
}
}
运行此代码,你会看到对于无效 JSON,json.Compact 返回了错误:
压缩结果: {"name":"Alice","age":30}
无效 JSON 压缩错误: unexpected end of JSON input
因此,你的文档修改建议是合理的。明确说明 json.Compact 同时验证 JSON 编码,可以帮助其他开发者避免不必要的验证调用。


