Go’s true can be false
Anyone that tackles the Go programming language for the first time is bound to be confused by some of the design decisions behind the language. Backward declarations, method syntax, integrated concurrency, lack of inheritance can all be strange initially, to say the least.
Using the language for a while and you start to understand what the developers of Go were aiming at. Using it a bit more and you start to appreciate it. You start to see how lightweight go routines can be better than threads and how native concurrency features can make the code much more robust. You learn that OOP inheritance is not as cool as you were once taught and is often best avoided.
What I am about to show you, however, is bound to make you cringe. Let’s have a look at a very simple piece of code.
package main
import "fmt"
func main() {
var status bool = true
if status {
fmt.Println("True")
} else {
fmt.Println("False")
}
}
Nothing out of the ordinary so far. Running the code produces True
on the standard output, as one would expect. It gets a lot more interesting when we add the following line to the code.
var true = false
We place it just before the function, resulting in the following code.
package main
import "fmt"
var true = false
func main() {
var status bool = true
if status {
fmt.Println("True")
} else {
fmt.Println("False")
}
}
By now, you are probably hoping that the compiler is dumping all sorts of error messages and that the title was simply a clickbait but, alas, that’s not the case. The program compiles and runs just fine. Except that this time you get False
on the standard output.
Bummer. It seems that you can override a constant and use it as a variable. What’s worst is that you can even do that with built-in types. Take a look at the following variation of the code.
package main
import "fmt"
var int = false
func main() {
var status bool = int
if status {
fmt.Println("True")
} else {
fmt.Println("False")
}
}
We are using int
as a variable. This can’t be good.
I filed an issue to the go project. Unfortunately, I failed to get a detailed explanation as to why this is allowed. What I know is that this will stick through all of the 1.x.x
versions of the language, due to the backward compatibility promise that has been made.
Still, all is not lost. Since all Go keywords are lowercase, overriding them will affect only the package at hand. There is no worry that a dependency can wreak havoc on your program. We can all go to sleep, knowing that our projects are safe.
I hope that this peculiar feature of Go was interesting to you and will not make you think any less of a language that has otherwise a lot to offer.
NOTE: This article has been ported from medium.