我应该在程序包级别但在http处理程序之外声明变量吗? [英] Should I declare variables in package level but outside of http handler?

查看:73
本文介绍了我应该在程序包级别但在http处理程序之外声明变量吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将gin gonic用作HTTP框架,并且需要像这样通过共享变量对一些路径进行分组:

  ur:= r.Group("/")ur.Use(package.Prepare){ur.GET("/",package.Home)} 

Prepare 处理程序中,我声明了包变量,例如 package.tplPath ,因为我希望所有子路由都可以访问此变量,而不是在每个http处理程序中重写代码.

  var tplPath ="func Prepare(c * gin.Context){_,文件名,_,_:= runtime.Caller(0)s:= helper.RelativeFilePath(文件名)tplPath = s [1:len(s)] +"template/"} 

我不知道Go如何与每个进程一起使用,以及每个HTTP请求的变量.如果在程序包级别声明了变量,那么是否会在每个http请求之后进行设置?

这被认为是好的做法吗?如果没有,为什么不呢?

解决方案

这不是线程安全的,包变量在所有goroutine中共享,并且在一个例程中进行修改将更改所有其他例程中的值,从而导致数据争用./p>

一般而言;尝试并尽可能避免使用包级变量.

修改:

在使用过程中,包是一种模块.对于任何给定的导入路径(基本上是包名称),仅存在一个包实例.这意味着在包级别只有1个任何变量的实例.

包变量是共享的全局状态.该变量的所有访问器都将访问完全相同的内存.

包变量的类型是什么,struct/string/int等都无关紧要.如果在包级别定义,则该变量的所有访问器都将共享它的相同实例.

如果(与http服务器一样)您具有并发代码,则该变量将同时存在多个访问器.在某些情况下,这很好,例如仅读取该变量时,但是在您看来,它将被修改.使此代码更加合理!

I'm using gin gonic as an HTTP framework and I need to group some paths with shared variable by like this:

ur := r.Group("/")
ur.Use(package.Prepare)
{
    ur.GET("/", package.Home)
}

Inside the Prepare handler, I declare package variable like package.tplPath because I want all sub routes can access to this variable instead of rewrite the code in each http handler.

var tplPath = ""

func Prepare(c *gin.Context) {
    _, filename, _, _ := runtime.Caller(0)
    s := helper.RelativeFilePath(filename)
    tplPath = s[1:len(s)] + "template/"
}

I don't know how Go works with each process, and variables for each http request. If a variable was declared in package level, will it be set after each http request?

Is this considered good practice? If not, why not?

解决方案

This is not threadsafe, package variables are shared across all goroutines, and modification in one routine will change the value in all the others, causing a data race.

In general; try and avoid using package level variables where possible.

Edit:

In go, packages are a kind of module. There exists only one instance of a package for any given import path (basically package name). This means that there is only 1 instance of any variable at package level.

Package variables are shared, global state. All accessors of that variable will be accessing the exact same memory.

It does not matter what type the package variable is, struct / string / int etc. If it is defined at package level, all accessors of that variable will share the same instance of it.

If (as with http servers) you have concurrent code, there will be multiple accessors of that variable at the same time. In some situations this is fine, like when that variable is only ever read, but it appears that in your case it will be modified. Making this code racy!

这篇关于我应该在程序包级别但在http处理程序之外声明变量吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆