Serialization/Encoding 在 json.NewEncoder 和 json.NewDecoder
Serialization/Encoding in json.NewEncoder and json.NewDecoder
我正在尝试通过使用 Go 中的 gorilla mux 库构建一个不同的基本 REST API 来学习后端开发(遵循这个 tutorial)
这是我到目前为止构建的代码:
package main
import (
"encoding/json"
"net/http"
"github.com/gorilla/mux"
)
// Post represents single post by user
type Post struct {
Title string `json:"title"`
Body string `json:"body"`
Author User `json:"author"`
}
// User is struct that represnets a user
type 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 中通过互联网传输的数据将以 bytes/binary 格式的形式发生(我猜是用 UTF-8 编码?)。所以 json.NewEncoder
正在将 Go 数据结构转换为 JSON 字符串,而 json.NewDecoder
正在做相反的事情(如果我错了请纠正我)。
- 那么谁负责将这个 JSON 字符串转换为 UTF-8
数据传输编码?这也是
json.NewDecoder
和 json.NewEncoder
的一部分吗
做什么?
- 另外,如果这2个功能只有serializing/de-serializing
to/from JSON,为什么名称编码器和解码器(不是编码
总是与二进制数据转换有关?)。老实说,我对术语
encoding
、serialization
、marshaling
以及它们之间的区别感到很困惑
谁能解释一下在每个转换级别(json、二进制、内存中数据结构),数据传输到底是如何发生的?
调用json.NewEncoder
产生的json.Encoder
直接以UTF-8格式产生输出。无需转换。 (事实上 ,Go 没有与 UTF-8 编码字节序列不同的文本数据表示 - 即使 string
只是一个不可变的字节数组。)
Go 使用术语 encode 进行序列化,使用 decode 进行反序列化,无论序列化形式是二进制还是文本.不要过多考虑术语——将 encode 和 seralise 视为同义词。
首先,我们必须明白,编码过程实际上并不意味着它将 types
和 returns 翻译成 type
的 JSON 表示。为您提供 JSON 表示的过程称为编组过程,可以通过调用 json.Marshal function.
来完成
另一方面,Encoding process means that we want to get the JSON encoding of any type
and to write(encode) it on a stream that implements io.Writer interface. As we can see the func NewEncoder(w io.Writer) *Encoder
receives an io.Writer
interface as a parameter and returns a *json.Encoder
object. When the method encoder.Encode()
is being called, it does the Marshaling process and then writes the result to the io.Writer that we have passed when creating a new Encoder object. You could see the implementation of json.Encoder.Encode() here.
所以,如果你问谁对http流进行编码处理,答案就是http.ResponseWriter
。 ResponseWriter 实现了 io.Writer 接口,当调用 Encode()
方法时,编码器会将对象编组为 JSON 编码表示,然后调用 func Write([]byte) (int, error)
这是一个合同io.Writer 接口的方法,它将执行对 http 流的写入过程。
总而言之,我可以说 Marshal 和 Unmarshal 意味着我们想要获得任何类型的 JSON 表示和 vice-versa。而 Encode 意味着我们要执行 Marshaling 过程,然后将结果写入(编码)到任何流对象。 Decode 意味着我们想从任何流中获取(解码)一个 json 对象,然后进行 Unmarshaling 过程。
我正在尝试通过使用 Go 中的 gorilla mux 库构建一个不同的基本 REST API 来学习后端开发(遵循这个 tutorial)
这是我到目前为止构建的代码:
package main
import (
"encoding/json"
"net/http"
"github.com/gorilla/mux"
)
// Post represents single post by user
type Post struct {
Title string `json:"title"`
Body string `json:"body"`
Author User `json:"author"`
}
// User is struct that represnets a user
type 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 中通过互联网传输的数据将以 bytes/binary 格式的形式发生(我猜是用 UTF-8 编码?)。所以 json.NewEncoder
正在将 Go 数据结构转换为 JSON 字符串,而 json.NewDecoder
正在做相反的事情(如果我错了请纠正我)。
- 那么谁负责将这个 JSON 字符串转换为 UTF-8
数据传输编码?这也是
json.NewDecoder
和json.NewEncoder
的一部分吗 做什么? - 另外,如果这2个功能只有serializing/de-serializing
to/from JSON,为什么名称编码器和解码器(不是编码
总是与二进制数据转换有关?)。老实说,我对术语
encoding
、serialization
、marshaling
以及它们之间的区别感到很困惑
谁能解释一下在每个转换级别(json、二进制、内存中数据结构),数据传输到底是如何发生的?
调用
json.NewEncoder
产生的json.Encoder
直接以UTF-8格式产生输出。无需转换。 (事实上 ,Go 没有与 UTF-8 编码字节序列不同的文本数据表示 - 即使string
只是一个不可变的字节数组。)Go 使用术语 encode 进行序列化,使用 decode 进行反序列化,无论序列化形式是二进制还是文本.不要过多考虑术语——将 encode 和 seralise 视为同义词。
首先,我们必须明白,编码过程实际上并不意味着它将 types
和 returns 翻译成 type
的 JSON 表示。为您提供 JSON 表示的过程称为编组过程,可以通过调用 json.Marshal function.
另一方面,Encoding process means that we want to get the JSON encoding of any type
and to write(encode) it on a stream that implements io.Writer interface. As we can see the func NewEncoder(w io.Writer) *Encoder
receives an io.Writer
interface as a parameter and returns a *json.Encoder
object. When the method encoder.Encode()
is being called, it does the Marshaling process and then writes the result to the io.Writer that we have passed when creating a new Encoder object. You could see the implementation of json.Encoder.Encode() here.
所以,如果你问谁对http流进行编码处理,答案就是http.ResponseWriter
。 ResponseWriter 实现了 io.Writer 接口,当调用 Encode()
方法时,编码器会将对象编组为 JSON 编码表示,然后调用 func Write([]byte) (int, error)
这是一个合同io.Writer 接口的方法,它将执行对 http 流的写入过程。
总而言之,我可以说 Marshal 和 Unmarshal 意味着我们想要获得任何类型的 JSON 表示和 vice-versa。而 Encode 意味着我们要执行 Marshaling 过程,然后将结果写入(编码)到任何流对象。 Decode 意味着我们想从任何流中获取(解码)一个 json 对象,然后进行 Unmarshaling 过程。