2D slices and arrays in Golang

Subtle, unexpected behaviour of Golang's slice "append"

Python leaky unittests Gotcha - Too Many MySQL Connections

OpenWorm - a long way to go

Open Source Software Presentation

I am a software engineer (lapsed physicist) who likes working with open source technology. I spend most of my time writing code in Python but I am currently also learning Go.

In Golang it is possible to allocate a 2D array, as long as the size of the array is known at compile time, for instance the following code:

package main

import (
    "fmt"
)

func main() {
    var MultiDimensionalArray [3][5]int

    MultiDimensionalArray[2][1]=5
    MultiDimensionalArray[1][1]=2

    fmt.Println(MultiDimensionalArray)

}

will print the following:

[[0 0 0 0 0] [0 2 0 0 0] [0 5 0 0 0]]

However, if we want to decide the size of the 2D array at runtime (dynamic allocation) we get an error:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    numColumns := rand.Intn(30)
    var MultiDimensionalArray [numColumns][5]int // Will Error: non-constant array bound numColumns
    fmt.Println(MultiDimensionalArray)
}

This is because the size of the array needs to be known at compile time (technically, it needs to be constant at compile time, there is a more detailed discussion of this on the go-nuts mailing list)

In Golang, when working with sequences of typed data it is much more common to utilise slices rather than arrays. When used correctly they have little to no overhead compared to arrays.

If we want a "2D slice" we actually want to construct a "slice of slices" as shown in this example

import (
    "fmt"
    "math/rand"
)

func main() {
    rand.Seed(10) //Initialize the random number generator with a seed
    numRows := rand.Intn(10) //4
    numColumns := rand.Intn(10) //8

    sliceOfSlices := make([][]int, numRows) //initialize the slice of slices
    for i := range sliceOfSlices {
       sliceOfSlices[i] = make([]int, numColumns) // intialize every slice within the slice of slices
    }

    fmt.Println(sliceOfSlices) // will print a 4x8 slice of slices
}

The builtin make function does not require the len of a slice to be known at compile time.

If, like me you find this slightly messy you may want to look at Gonum Matrix. Although I haven't used it yet, it appears to be the nearest thing Golang has to Python's numpy.