我正在编写一个小型的Web服务器程序,它会根据POST请求进行大量的JSON解码。
最初,我认为每次请求进入时都不会初始化新的json.Decoder
,而是将其作为一个全局变量,每次都被调用,并与goroutines同时解码。
作为Go的新手,这没关系吗?是否有时候我不应该这样做,而且由于不是线程安全,课程会变得怪异(我猜" goroutine"安全会更好)?
答案 0 :(得分:6)
在Go中,json.NewDecoder将io.Reader作为输入参数并返回* json.Decoder。因此,不可能重用相同的Decoder,因为我们为每个POST请求都有不同的http.Request.Body(实现io.Reader)。
正如Paul Hankin所提到的,你不能同时使用go对象,除非它们被记录为可以安全地同时使用。
示例:
- 醇>
http.Client& http.Transport
客户和运输是安全的 多个goroutine同时使用并且仅用于效率 创建一次并重复使用。
- 醇>
地图
经过长时间的讨论后,决定通常使用地图不需要从多个goroutine安全访问。
如果您询问重用JSON解码器以避免重复代码,您可以查看Tigertonic和Go-Json-Rest等框架。
在旁注中,您可以查看ffjson以加快JSON解码。
答案 1 :(得分:2)
就像约翰和保罗所说,这不会做你期望的事情。
如果您主要关心的是代码重复,那么您可能需要的是中间件。这是一个如何做到这一点的例子
type JSONHandler func(http.ResponseWriter, *http.Request, *json.Decoder)
func JSONMiddleware(handler JSONHandler) http.HandlerFunc{
return func(w http.ResponseWriter, req *http.Request) {
decoder := json.NewDecoder(req.Body)
handler(w, req, decoder)
}
}
func MyHandler(w http.ResponseWriter, req *http.Request, decoder *json.Decoder) {
// Put your code here, you have access to the decoder
}
func main() {
http.HandleFunc("/myroute", JSONMiddleware(MyHandler))
...
}