I’ve been spending the last few weeks learning Go by reading Learning Go by Jon Bodner, so far I’ve been enjoying learning about Go, though there is still one thing I keep tripping over, in Go, you can return one or more values, for me Go is the first language that I have worked with that does that, in every other language I had to introduce a custom discriminating union to achieve what Go does natively.

Take the following Go code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
func twoSum(nums []int, target int) []int {
    s := make(map[int]int)

    for idx, num := range nums {
        if pos, ok := s[target-num]; ok {
            return []int{pos, idx}
        }
        s[num] = idx
    }
    return []int{}
}

Most of it can be understood even by those that have never worked with Go, the part that I was having a rough time understanding was the if statement below.

1
2
3
if pos, ok := s[target-num]; ok {
    return []int{pos, idx}
}

I wasn’t understanding how the variable “ok” could evaluate to true, I’ve worked so much with C# that my brain naturally tried to read the code as if it were C#, and in C# like many other objection-oriented languages you can only return one value. Looking at the official docs I found the following note under Index Expression.

An index expression on a map of type map[K]V used in an assignment statement or initialization of the special form yields an additional untyped boolean value. The value of ok is true if the key x is present in the map, and false otherwise.

In other words, in the example above if target minus sum yields a value, that value is assigned to the variable pos, and the untyped boolean value is assigned to the variable “ok”, then the variable “ok” is evaluated.