在Go中同时使用变量总是可行的吗?

时间:2016-04-28 00:20:05

标签: json go

我正在编写一个小型的Web服务器程序,它会根据POST请求进行大量的JSON解码。

最初,我认为每次请求进入时都不会初始化新的json.Decoder,而是将其作为一个全局变量,每次都被调用,并与goroutines同时解码。

作为Go的新手,这没关系吗?是否有时候我不应该这样做,而且由于不是线程安全,课程会变得怪异(我猜" goroutine"安全会更好)?

2 个答案:

答案 0 :(得分:6)

在Go中,json.NewDecoder将io.Reader作为输入参数并返回* json.Decoder。因此,不可能重用相同的Decoder,因为我们为每个POST请求都有不同的http.Request.Body(实现io.Reader)。

正如Paul Hankin所提到的,你不能同时使用go对象,除非它们被记录为可以安全地同时使用。

示例:

  
      
  1. http.Client& http.Transport

         

    客户和运输是安全的   多个goroutine同时使用并且仅用于效率   创建一次并重复使用。

  2.   

Source

  
      
  1. 地图

         

    经过长时间的讨论后,决定通常使用地图不需要从多个goroutine安全访问。

  2.   

Source

如果您询问重用JSON解码器以避免重复代码,您可以查看TigertonicGo-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))
    ...
}

(在操场上:https://play.golang.org/p/4ZTaQguNj7