我使用 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) {
_, filename, _, _ := runtime.Caller(0)
s := helper.RelativeFilePath(filename)
tplPath = s[1:len(s)] + "template/"
}
我不知道 Go 如何处理每个进程,以及每个 http 请求的变量。如果在包级别声明了一个变量,它会在每个 http 请求后设置吗?
这被认为是好的做法吗?如果不是,为什么不呢?
最佳答案
这不是线程安全的,包变量在所有 goroutine 之间共享,修改一个例程会更改所有其他例程中的值,从而导致数据竞争。
一般来说;尽可能避免使用包级变量。
编辑:
在 go 中,包是一种模块。对于任何给定的导入路径(基本上是包名称),只存在一个包实例。这意味着在包级别只有 1 个变量实例。
包变量是共享的全局状态。该变量的所有访问器都将访问完全相同的内存。
无论包变量是什么类型,struct/string/int 等。如果它是在包级别定义的,该变量的所有访问器将共享它的同一个实例。
如果(对于 http 服务器)您有并发代码,那么该变量将同时有多个访问器。在某些情况下,这很好,例如仅读取该变量时,但在您的情况下,它似乎会被修改。让这段代码充满活力!
关于go - 我应该在包级别但在 http 处理程序之外声明变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50844390/