> The one tiny drawback is that the globals have to be variables instead of constants, but that’s one of those problems that really only exists in the theoretical realm. I’ve never seen a bug from someone overwriting a global variable like this, that is intended to be immutable.

Even if it’s a silly bug to make, it really annoys me a lot knowing you could change an enum value. Is it so hard for Go to support consts of any-type?

Although an improvement over C, Go seems to have the same unofficial motto: "I don't need you to X, just trust me to Y", as in:

1) I don't need you to prevent me from mutating this variable, just trust me to not mutate it.

2) I don't need you to ensure I handle every case of this enum, just trust me to update all the relevant code whenever I add a new case.

3) I don't need you to prevent me from reading the result without checking the error, just trust me to always handle errors.

4) I don't need you to track nullability in the type system, just trust me not to dereference null pointers.

5) I don't need you to let me hide the default constructor, just trust me to always use the smart constructor that establishes the invariants that I need.

6) Until recently: I don't need you to let me abstract away this type, just trust me to keep all the copies of the function/type in sync.

This philosophy may make sense for a low-level language like C, but not for a high-level language for building applications, services, etc. It amazes me that people voluntarily give up the guarantees of other languages in favor of Go for these use cases. It's almost as if the language wants bugs to slip into your code.

There are linters available that help you do the "just trust me to" part.

Edit: https://github.com/nishanths/exhaustive is available in golangci-lint