Variables scope in Golang & the compilation process

As I started this blog, I thought that I should really understand Hugo for my personal interest and for some upcoming projects, and while digging further, I found myself delving into Go and I started consuming the content of random sites, YouTube videos of Go introductions and plenty of Gopher conferences but and started some spaghetti code and built my own Go RSS to Hugo Markdown, which I’m planning to release some time soon, in order to build a news aggregator based on Hugo! Well, what was not the goal but to test chemistry with the language before delving further.

Then I decided to take it step up and read a book, particularly after watching a couple of videos for Dave Cheney where he explains the philosophy behind things in Go, which resonated well with me. There are many books on Go but the one which luckily was available to me and then is highly recommended by the community, is The Go Programming Language by Alan Donovan and the great Brian Kernighan.

and as I started reading, early in the book the introduction to *ways to declare a string in a variable in Go with the following list of possibilities that are equivalent:

s := "" // compact and used within a function, not for package-level variable
var s string // relies on the default initialization to the zero value for strings, which is ""
var s = "" //
var s string = ""

And quoting the authors, with high hopes and good intentions, that I’m not violating any copyright by doing so:

Why should you prefer one form to another? The first form, a short variable declaration, is the most compact, but it may be used only within a function, not for package-level variables. The second form relies on default initialization to the zero value for strings, which is “". The third form is rarely used except when declaring multiple variables. The fourth form is explicit about the variable’s type, which is redundant when it is the same as that of the initial value but necessary in other cases where they are not of the same type. In practice, you should generally use one of the first two forms, with explicit initialization to say that the initial value is important and implicit initialization to say that the initial value doesn’t matter.

And, as I’m new to Go, I have some baby questions like the one that my inner monologue started to irritating me while trying to concentrate on continues reading, “why go compiler complains against unused declared value inside a function, but not when declared at package level?” The question was raised because so far it appears that almost everything is based on some philosophy in Go.

I headed up to the community, #go-nuts on Freenode, which I should highly appreciate their high-patience with a political science background programmer who’s trying to understand things and this fired up an interested short discussion of why it is within the design? Particularly because Go doesn’t allow declaring a func-level-variable without using it and would proudly complain against it with declared but not used but then why it’s not the case with package-level-variables? and is it silently dropped or simply not complained against as it’s meant to be accessible by other packages as well?

For reason or another, I’m simply not satisfied with the current answer, which simply stating that unused package level declaration are silently dropped, and I’m not satisfied because if the “philosophical standards” approves removing dead code at package level, then it should apply to func level, despite I’m with the notion of preferring raising the error in both cases, package & func.

So I turned the question to the Golang Forum for further discussion and there is a suggestion that I might have been stumbling into unvisited territory and this might constitute a bug, and the recommendation was to email go-nuts which I did.

Now, despite that this question took away my attention from the book but through this journey I learned about the different steps in the compilation/build process in Go’s perspective.

I will be either updating this post with the answers.

Ian answer

#Go-nuts mailing list and Ian Lance Taylor who is the author of Go frontend for GCC and Go team member, provided the following answer.

Package scope variables can provide hooks for other packages (if the variables are exported) or for debuggers to change program behavior. There’s no easy way for the compiler or linker to know whether this might happen. In particular the compiler (perhaps unfortunately) supports a go:linkname directive that can reach into another package and refer to a package-scope variable. This is generally not good practice but there is existing code that does it.

I don’t fully understand the details in Ian’s response but that should be the case for a newcomer to the language trying to understand certain areas that require some experience with the language and its underlying tools.


Unfortunately I couldn’t yet dedicate the time to figure out how to get Commento or similar comment system on App Engine but hopefully soon. If you have tips on this, you can tweet to me @jadmadi