为什么json包是';这里使用的解码和封送处理方法是什么?
在以下来自的示例中,用于为每个HTTP请求使用新的MongoDB会话实现HTTP服务器:为什么json包是';这里使用的解码和封送处理方法是什么?,json,go,Json,Go,在以下来自的示例中,用于为每个HTTP请求使用新的MongoDB会话实现HTTP服务器: 为什么在PostCategory函数中使用json包的Decode方法 为什么在GetCategories函数中使用json包的Marshal方法 起初我认为PostCategory中的Decode和GetCategories中的Marshal是相反的,但后来我发现在json包中有一个Unmarshal方法,可能还有一个Encode方法。所以我早些时候问过 这是节目单 package main impo
- 为什么在
函数中使用PostCategory
包的json
方法Decode
- 为什么在
函数中使用GetCategories
包的json
方法Marshal
PostCategory
中的Decode
和GetCategories
中的Marshal
是相反的,但后来我发现在json
包中有一个Unmarshal
方法,可能还有一个Encode
方法。所以我早些时候问过
这是节目单
package main
import (
"encoding/json"
"log"
"net/http"
"github.com/gorilla/mux"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
var session *mgo.Session
type (
Category struct {
Id bson.ObjectId `bson:"_id,omitempty"`
Name string
Description string
}
DataStore struct {
session *mgo.Session
}
)
//Close mgo.Session
func (d *DataStore) Close() {
d.session.Close()
}
//Returns a collection from the database.
func (d *DataStore) C(name string) *mgo.Collection {
return d.session.DB("taskdb").C(name)
}
//Create a new DataStore object for each HTTP request
func NewDataStore() *DataStore {
ds := &DataStore{
session: session.Copy(),
}
return ds
}
//Insert a record
func PostCategory(w http.ResponseWriter, r *http.Request) {
var category Category
// Decode the incoming Category json
err := json.NewDecoder(r.Body).Decode(&category)
if err != nil {
panic(err)
}
ds := NewDataStore()
defer ds.Close()
//Getting the mgo.Collection
c := ds.C("categories")
//Insert record
err = c.Insert(&category)
if err != nil {
panic(err)
}
w.WriteHeader(http.StatusCreated)
}
//Read all records
func GetCategories(w http.ResponseWriter, r *http.Request) {
var categories []Category
ds := NewDataStore()
defer ds.Close()
//Getting the mgo.Collection
c := ds.C("categories")
iter := c.Find(nil).Iter()
result := Category{}
for iter.Next(&result) {
categories = append(categories, result)
}
w.Header().Set("Content-Type", "application/json")
j, err := json.Marshal(categories)
if err != nil {
panic(err)
}
w.WriteHeader(http.StatusOK)
w.Write(j)
}
func main() {
var err error
session, err = mgo.Dial("localhost")
if err != nil {
panic(err)
}
r := mux.NewRouter()
r.HandleFunc("/api/categories", GetCategories).Methods("GET")
r.HandleFunc("/api/categories", PostCategory).Methods("POST")
server := &http.Server{
Addr: ":8080",
Handler: r,
}
log.Println("Listening...")
server.ListenAndServe()
}
我认为这里使用
json.NewDecoder
的主要原因是直接从响应体(r.body
)读取,因为NewDecoder
将io.Reader
作为输入
您可以使用
json.Unmarshal
,但随后必须首先将响应正文读入[]字节
,并将该值传递给json.Unmarshal
NewDecoder
在这里更方便。我认为使用json的主要原因。NewDecoder
在这里直接从响应体(r.body
)读取,因为NewDecoder
将io.Reader
作为输入
您可以使用
json.Unmarshal
,但随后必须首先将响应正文读入[]字节
,并将该值传递给json.Unmarshal
NewDecoder
在这里更方便。TL;DR-封送
/解组
获取并返回字节片,而编码
/解码
执行相同的操作,但从网络连接(读写器)等流中读取字节
包使用和类型对数据流进行操作,即“和”。这意味着您可以直接从网络套接字(或者在本例中是实现io.Reader
)获取数据,并在字节进入时将其转换为JSON。通过这种方式,我们可以在任何数据可用但尚未收到整个文档之前立即开始处理JSON(在与大文档的慢速网络连接上,这可以节省我们很多时间,对于一些具有“无限大小”文档流的流协议,这是绝对必要的!)
Marshal
和Unmarshal
不过是在字节片上操作的,这意味着您必须将整个JSON文档存储在内存中,然后才能使用它们。在您的示例中,作者使用Marshal是因为他们已经有了一个[]字节
片,所以没有必要使用字节片构造一个缓冲区,然后制作一个使用该缓冲区的编码器,然后调用encode:相反,他们可以让Marshal为他们这样做
实际上,封送/解封只是编码器和解码器之上的方便方法。如果我们看一下,我们会发现它只是在构建一个编码器(或者编码器的内部表示,但是相信我,它们是一样的,如果你想证明的话,你可以看一下,它也在创建一个编码状态
),然后返回输出字节:
TL;DR-
封送
/解组
获取并返回字节片,而编码
/解码
执行相同的操作,但从网络连接(读写器)等流中读取字节
包使用和类型对数据流进行操作,即“和”。这意味着您可以直接从网络套接字(或者在本例中是实现io.Reader
)获取数据,并在字节进入时将其转换为JSON。通过这种方式,我们可以在任何数据可用但尚未收到整个文档之前立即开始处理JSON(在与大文档的慢速网络连接上,这可以节省我们很多时间,对于一些具有“无限大小”文档流的流协议,这是绝对必要的!)
Marshal
和Unmarshal
不过是在字节片上操作的,这意味着您必须将整个JSON文档存储在内存中,然后才能使用它们。在您的示例中,作者使用Marshal是因为他们已经有了一个[]字节
片,所以没有必要使用字节片构造一个缓冲区,然后制作一个使用该缓冲区的编码器,然后调用encode:相反,他们可以让Marshal为他们这样做
实际上,封送/解封只是编码器和解码器之上的方便方法。如果我们看一下,我们会发现它只是在构建一个编码器(或者编码器的内部表示,但是相信我,它们是一样的,如果你想证明的话,你可以看一下,它也在创建一个编码状态
),然后返回输出字节:
谢谢你是说
Unmarshal
和Decode
可以应用于同一个对象,唯一的区别是该对象应该被视为Unmarshal
的字节数组,而该对象应该被视为io.Reader
对象?这基本上就是这个想法。事实上,如果您查看解码
的源代码,您将看到它在内部也使用解组
(尽管定义为私有包成员。()另外,Decode
在您有一个实现json.Unmarshaler
接口的类型时非常有用,因为它可以用于解码嵌套结构。例如,谢谢。您的意思是Unmarshal
和Decode
可以应用于同一个对象,唯一的区别是该对象应该被视为字节数组吗小于cod的y
func Marshal(v interface{}) ([]byte, error) {
e := &encodeState{}
err := e.marshal(v)
if err != nil {
return nil, err
}
return e.Bytes(), nil
}