为了账号安全,请及时绑定邮箱和手机立即绑定

json.NewEncoder 和 json.NewDecoder 中的序列化/编码

json.NewEncoder 和 json.NewDecoder 中的序列化/编码

Go
UYOU 2022-06-27 09:20:18
我正在尝试通过在 Go 中使用 gorilla mux 库构建一个不同的基本 REST API 来学习后端开发(遵循本教程)这是我到目前为止构建的代码:package mainimport ("encoding/json""net/http""github.com/gorilla/mux")// Post represents single post by usertype Post struct {Title  string `json:"title"`Body   string `json:"body"`Author User   `json:"author"`}// User is struct that represnets a usertype User struct {FullName string `json:"fullName"`Username string `json:"username"`Email    string `json:"email"`}var posts []Post = []Post{}func main() {   router := mux.NewRouter()   router.HandleFunc("/posts", addItem).Methods("POST")   http.ListenAndServe(":5000", router)}func addItem(w http.ResponseWriter, req *http.Request) {   var newPost Post   json.NewDecoder(req.Body).Decode(&newPost)   posts = append(posts, newPost)   w.Header().Set("Content-Type", "application/json")   json.NewEncoder(w).Encode(posts)}但是,我真的很困惑到底发生了json.NewDecoder什么json.NewEncoder。据我了解,最终以 REST API 通过 Internet 传输的数据将以字节/二进制格式(我猜是 UTF-8 编码?)的形式发生。json.NewEncoder将 Go 数据结构转换为 JSON 字符串也是如此,并且json.NewDecoder正在做相反的事情(如果我错了,请纠正我)。那么这里谁负责将这个 JSON 字符串转换为 UTF-8 编码进行数据传输呢?这也是做什么json.NewDecoder和json.NewEncoder 做什么的一部分吗?此外,如果这两个函数只是对 JSON 进行序列化/反序列化,那么为什么要命名编码器和解码器(编码不是总是与二进制数据转换相关吗?)。老实说,我对这些术语encoding以及它们之间的区别感到很困惑serializationmarshaling有人能解释一下每个转换级别(json、二进制、内存数据结构)的数据传输到底是如何发生的吗?
查看完整描述

2 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

首先,我们必须了解编码过程实际上并不意味着它会翻译types并返回 a 的 JSON 表示type。为您提供 JSON 表示的过程称为编组过程,可以通过调用json.Marshal 函数来完成。

另一方面,Encoding过程意味着我们想要获取 any 的 JSON 编码type并将其写入(编码)到实现 io.Writer 接口的流上。正如我们所见,func NewEncoder(w io.Writer) *Encoder接收一个io.Writer接口作为参数并返回一个*json.Encoder对象。调用该方法时encoder.Encode(),它会执行 Marshaling 过程,然后将结果写入我们在创建新 Encoder 对象时传递的 io.Writer 中。你可以在这里看到 json.Encoder.Encode() 的实现。

所以,如果你问是谁对 http 流进行编码处理,答案是http.ResponseWriter. ResponseWriter 实现了 io.Writer 接口,在Encode()调用该方法时,编码器会将对象编组为 JSON 编码表示,然后调用func Write([]byte) (int, error)io.Writer 接口的一个契约方法,它会对http 流。

总之,我可以说 Marshal 和 Unmarshal 意味着我们想要获得任何类型的 JSON 表示,反之亦然。而编码意味着我们要进行编组处理,然后将结果写入(编码)到任何流对象。而解码意味着我们想要从任何流中获取(解码)一个 json 对象,然后执行 Unmarshaling 过程。


查看完整回答
反对 回复 2022-06-27
?
达令说

TA贡献1821条经验 获得超6个赞

  1. json.Encoder调用产生的json.NewEncoder直接以 UTF-8 产生其输出。无需转换。(事实上,Go 没有与 UTF-8 编码的字节序列不同的文本数据表示形式——即使 astring只是底层的不可变字节数组。)

  2. Go 使用术语编码进行序列化和解码用于反序列化,无论序列化形式是二进制形式还是文本形式。不要过多考虑术语——将encodeseralise视为同义词。


查看完整回答
反对 回复 2022-06-27
  • 2 回答
  • 0 关注
  • 801 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信