“net/http”在golang中使用全局变量被认为是一种良好的实践吗?

huangapple go评论79阅读模式
英文:

Is "net/http"'s use of global variables considered a good practice in golang?

问题

golang包"net/http"使用全局变量DefaultServeMux来注册处理程序。这被认为是一种良好的实践,甚至是一种golang习语吗?毕竟它是一个全局变量。

不使用全局变量的两个主要原因是,据我所知,1)它们增加了复杂性,2)在并发程序中存在问题。

也许在这种情况下,1)不被认为是重要的,因为开发人员可以选择不使用DefaultServerMux?那2)呢?在Go中,全局变量是否总是线程/ goroutine安全的?尽管如此,我对它在Go的标准库中的使用感到惊讶。我从未在其他语言/标准库中见过这样的做法。

英文:

The golang package "net/http" uses the global variable DefaultServeMux to register handlers. Is this considered a good practice or even an golang idiom? Is it a global variable after all?

The two main reasons not to use global variables are AFAIK 1) that they add to complexity and 2) are problematic in concurrent programs.

Maybe 1) is not considered important in this case because the developer can choose not to use DefaultServerMux? What about 2)? Are global variables always thread/goroutine safe in Go? Still, I'm surprised that it's used in Go's standard library. I've never seen such practice in other languages / standard libraries.

答案1

得分: 22

是的。这个变量在根级别上定义,使其在整个包中都是全局的。

然而,这不是一个存储net/http包中所有敏感信息的全局变量。它只是一个方便的设置,使用net/http包的内容为用户提供了一个快速入门的机会。这也意味着它并不增加太多复杂性。

在我看来,这是一种帮助用户使用包的良好实践。如果你发现通过提供一个良好的默认配置可以节省用户的时间,那就这样做。

然而,当你要导出变量时,你应该小心。它们应该准备好进行并发访问。例如,DefaultServeMux(或者更好的是底层的ServeMux)使用互斥锁来保证线程安全。

不。在Go中,没有适当的同步(互斥锁、通道等),所有并发访问的东西都是有问题的,很可能会导致一切崩溃。

我从未在其他语言/标准库中见过这样的做法。例如,Python的logging模块提供了一个函数来获取根日志对象,可以调用其方法来自定义日志行为。这可以看作是一个全局对象,因为它是可变的并在模块中定义的。

英文:

> Is it a global variable after all?

Yes. The variable is defined on root level, which makes it global throughout the package.

However, this is not a global variable which stores all the sensible information
of the net/http package. It is merely a convenience setup which uses the content of
the net/http package to provide an quickstart opportunity to the user.
This also means, that is does not add much complexity.

> Is this considered a good practice or even an golang idiom?

IMO, it is good practice to aid the user with the usage of a package.
If you're finding that you could save the user some time by providing a
good default configuration, do so.

However, you should be careful when you're about to export variables.
They should be made ready for concurrent access.
The DefaultServeMux (or better, the underlying ServeMux), for example, is using a mutex to be thread safe.

> Are global variables always thread/goroutine safe in Go?

No. Without proper synchronization (mutex, channel, ...), everything that is accessed concurrently is problematic and will most certainly blow everything to bits and pieces.

> I've never seen such practice in other languages / standard libraries.

Python's logging module, for example, provides a function to retrieve the root logging object, which one can call methods on to customize the logging behaviour. This could be seen as a global object, as it is mutable and defined in the module.

答案2

得分: 1

The globvar is, in this case, as safe and as good choice as the analogue seen in e.g package "log" is.

IOW, claim 1 is as vague as it can get and claim 2 is constrained: sometime/somewhere true, otherwise false == doesn't hold in general even though used just like that.

英文:

The globvar is, in this case, as safe and as good choice as the analogue seen in e.g package "log" is.

IOW, claim 1 is as vague as it can get and claim 2 is constrained: sometime/somewhere true, otherwise false == doesn't hold in general even though used just like that.

huangapple
  • 本文由 发表于 2012年9月2日 03:17:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/12230643.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定