Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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.

like image 857
Christian Avatar asked Sep 01 '12 19:09

Christian


People also ask

Is it good practice to use global variables?

Using global variables causes very tight coupling of code. Using global variables causes namespace pollution. This may lead to unnecessarily reassigning a global value. Testing in programs using global variables can be a huge pain as it is difficult to decouple them when testing.

Are there global variables in Golang?

Golang Global Variable Typically, global variables are defined on top of the program before the main function. After declaration, a global variable can be accessed and changed at any part of the program.

Is it better to use mostly global or mostly local variables in your code?

Always prefer local over global. If you need to pass the data in as multiple parameters, so be it. At least then you're explicitly saying what data your function depends on. Having too many parameters is certainly a problem, but offloading some of them as globals isn't the answer.

When would it be suitable to use a global variable?

Global variables should be used when multiple functions need to access the data or write to an object. For example, if you had to pass data or a reference to multiple functions such as a single log file, a connection pool, or a hardware reference that needs to be accessed across the application.


2 Answers

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.

like image 148
nemo Avatar answered Sep 19 '22 07:09

nemo


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.

like image 24
zzzz Avatar answered Sep 20 '22 07:09

zzzz