Golang: What is Truth?

When I transitioned from writing Javascript into writing Golang, I quickly realized that there was a big difference in what it means for something to be truthy.

Truthiness in JavaScript

If you're unfamiliar with the term truthy, it means that a non-boolean type value (for instance, string, number, null) can be evaluated to a boolean. A fairly common example of that in javascript is to evaluate a string's truthiness before doing something with it:

let foo = "";

if (foo) { // "" evaluates to false, since it is empty
    console.log("the fu is strong with you");
}

foo = "foo";

if (foo) { // "foo" is true since it contains a string of length > 0
    console.log("how in the world can a string be true?!");
}

Another example is to check the value of an number:

let isGreaterThanZero = 0;

if (isGreaterThanZero) { // 0 evaluates to false, because 0 is "empty"
    console.log("it's greater than zero.");
}

isGreaterThanZero = 1;
if (isGreaterThanZero) { // any number that's _not_ zero evalutes to true
    console.log("it's greater than zero.");
}

When you've written javascript for a long time, boolean evaluation not only feels normal, it becomes surprising when a string doesn't evaluate to a boolean.

What is Truth in Golang

In Golang, there's only one type that has truthiness: booleans.

It makes sense right? That whole "if it quacks like a duck" analogy makes it a lot easier to know what your value is, but it also means that if you come from a language where you relied on boolean coercion, you need a major paradigm shift in how you check the truthiness of a non-boolean value.

Strings

As far as I've seen, there are two idiomatic ways in golang to test if a string is true:

  • test if a string has a length greather than 0
  • test if a string is not equal to an empty string ("")
package main

import "fmt"

func main() {
    s := "hello"
    if len(s) > 0 {
        fmt.Println("this string is not nil")
    }
        
    if s != "" {
        fmt.Println("this string is not empty")
    }
}

Numbers

Alternatively, for numbers, check if the value is greater than 0:

package main

import "fmt"

func main() {
    n := 1
    if n > 0 {
        fmt.Println("this number is greater than 0")
    }
}

Wrapping Up

This was a big mental shift for me, since javascript took care of coercion for me, but once I was able to make the shift, I realized that relying on coercion made my code more likely to have bugs.

The big takeaway here is that Golang does not have automatic type coercion for values that aren't of type bool and those values have to be checked against an empty value for the type you're using.

Was this article useful? Share it on Twitter!
Tags