Lesson 16. Arrayed in splendor

After reading lesson 16, you’ll be able to

  • Declare and initialize arrays
  • Assign and access the elements of an array
  • Iterate through arrays

Arrays are ordered collections of elements with a fixed length. This lesson uses arrays to store the names of planets and dwarf planets in our solar system, but you can collect anything you like.

Consider this

Do you have a collection or did you in the past? Maybe stamps, coins, stickers, books, shoes, trophies, movies, or something else?

Arrays are for collecting many of the same type of thing. What collections could you represent with an array?

16.1. Declaring arrays and accessing their elements

The following planets array contains exactly eight elements:

var planets [8]string

Every element of an array has the same type. In this case, planets is an array of strings.

Individual elements of an array can be accessed by using square brackets [] with an index that begins at 0, as illustrated in figure 16.1 and shown in listing 16.1.

Listing 16.1. Array of planets: array.go
var planets [8]string

planets[0] = "Mercury"         1
planets[1] = "Venus"
planets[2] = "Earth"

earth := planets[2]            2
fmt.Println(earth)             3

  • 1 Assigns a planet at index 0
  • 2 Retrieves the planet at index 2
  • 3 Prints Earth
Figure 16.1. Planets with indices 0 through 7

Even though only three planets have been assigned, the planets array has eight elements. The length of an array can be determined with the built-in len function. The other elements contain the zero value for their type, an empty string:

fmt.Println(len(planets))         1
fmt.Println(planets[3] == "")     2

  • 1 Prints 8
  • 2 Prints true
Note

Go has a handful of built-in functions that don’t require an import statement. The len function can determine the length for a variety of types. In this case it returns the size of the array.

Quick check 16.1

1

How do you access the first element of the planets array?

2

What is the default value for elements of a new array of integers?

QC 16.1 answer

1

planets[0]

2

Elements of an array are initially the zero value for the array’s type, which means 0 for integer arrays.

 

16.2. Don’t go out of bounds

An eight-element array has indices from 0 through 7. The Go compiler will report an error when it detects access to an element outside of this range:

var planets [8]string

planets[8] = "Pluto"         1
pluto := planets[8]          1

  • 1 Invalid array index 8 (out of bounds for 8-element array)

If the Go compiler is unable to detect the error, your program may panic while it’s running:

var planets [8]string

i := 8
planets[i] = "Pluto"         1
pluto := planets[i]          1

  • 1 Panic: runtime error: index out of range

A panic will crash your program, which is still better than modifying memory that doesn’t belong to the planets array, leading to unspecified behavior (as is the case with the C programming language).

Quick check 16.2

Q1:

Will planets[11] cause an error at compile-time or a panic at runtime?

QC 16.2 answer

1:

The Go compiler will detect an invalid array index.

 

16.3. Initialize arrays with composite literals

A composite literal is a concise syntax to initialize any composite type with the values you want. Rather than declare an array and assign elements one by one, Go’s composite literal syntax will declare and initialize an array in a single step, as shown in the following listing.

Listing 16.2. Array of dwarf planets: dwarfs.go
dwarfs := [5]string{"Ceres", "Pluto", "Haumea", "Makemake", "Eris"}

The curly braces {} contain five comma-separated strings to populate elements of the new array.

With larger arrays, breaking the composite literal across multiple lines can be more readable. And as a convenience, you can ask the Go compiler to count the number of elements in the composite literal by specifying the ellipsis ... instead of a number. The planets array in the following listing still has a fixed length.

Listing 16.3. A full array of planets: composite.go
planets := [...]string{      1
    "Mercury",
    "Venus",
    "Earth",
    "Mars",
    "Jupiter",
    "Saturn",
    "Uranus",
    "Neptune",               2
}

  • 1 The Go compiler counts the elements.
  • 2 The trailing comma is required.

Quick check 16.3

Q1:

How many planets are there in listing 16.3? Use the len built-in function to find out.

QC 16.3 answer

1:

The planets array has eight elements (8).

 

16.4. Iterating through arrays

Iterating through each element of an array is similar to iterating over each character of a string in lesson 9, as shown in the following listing.

Listing 16.4. Looping through an array: array-loop.go
dwarfs := [5]string{"Ceres", "Pluto", "Haumea", "Makemake", "Eris"}

for i := 0; i < len(dwarfs); i++ {
    dwarf := dwarfs[i]
    fmt.Println(i, dwarf)
}

The range keyword provides an index and value for each element of an array with less code and less chance for mistakes, as shown in the next listing.

Listing 16.5. Iterating through an array with range: array-range.go
dwarfs := [5]string{"Ceres", "Pluto", "Haumea", "Makemake", "Eris"}

for i, dwarf := range dwarfs {
    fmt.Println(i, dwarf)
}

Both listings 16.4 and 16.5 produce the same output:

0 Ceres
1 Pluto
2 Haumea
3 Makemake
4 Eris
Note

Remember that you can use the blank identifier (underscore) if you don’t need the index variable provided by range.

Quick check 16.4

1

What mistakes can be avoided by using the range keyword to iterate over an array?

2

When would it be appropriate to use a conventional for loop instead of range?

QC 16.4 answer

1

With the range keyword, the loop is simpler and avoids mistakes like going out of bounds (for example, i <= len(dwarfs)).

2

If you need something custom, like iterating in reverse or accessing every second element.

 

16.5. Arrays are copied

Assigning an array to a new variable or passing it to a function makes a complete copy of its contents, as you can see in the following listing.

Listing 16.6. Arrays are values: array-value.go
planets := [...]string{
    "Mercury",
    "Venus",
    "Earth",
    "Mars",
    "Jupiter",
    "Saturn",
    "Uranus",
    "Neptune",
}

planetsMarkII := planets         1

planets[2] = "whoops"            2

fmt.Println(planets)             3
fmt.Println(planetsMarkII)       4

  • 1 Copies planets array
  • 2 Makes way for an interstellar bypass
  • 3 Prints [Mercury Venus whoops Mars Jupiter Saturn Uranus Neptune]
  • 4 Prints [Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune]
Tip

In the event that you escape the destruction of Earth, you will want Go installed on your own computer. See the instructions at golang.org.

Arrays are values, and functions pass by value, which means the terraform function in the following listing is completely ineffective.

Listing 16.7. Arrays pass by value: terraform.go
package main

import "fmt"

// terraform accomplishes nothing
func terraform(planets [8]string) {
    for i := range planets {
        planets[i] = "New " + planets[i]
    }
}

func main() {
    planets := [...]string{
        "Mercury",
        "Venus",
        "Earth",
        "Mars",
        "Jupiter",
        "Saturn",
        "Uranus",
        "Neptune",
    }

    terraform(planets)
    fmt.Println(planets)           1
}

  • 1 Prints [Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune]

The terraform function is operating on a copy of the planets array, so the modifications don’t affect planets in the main function.

Also, it’s important to recognize that the length of an array is part of its type. The type [8]string and type [5]string are both collections of strings, but they’re two different types. The Go compiler will report an error when attempting to pass an array of a different length:

dwarfs := [5]string{"Ceres", "Pluto", "Haumea", "Makemake", "Eris"}
terraform(dwarfs)                                                       1

  • 1 Can’t use dwarfs (type [5]string) as type [8]string in argument to terraform

For these reasons, arrays aren’t used as function parameters nearly as often as slices, covered in the next lesson.

Quick check 16.5

1

How did Earth survive in planetsMarkII of listing 16.6?

2

How could listing 16.7 be modified so that the planets array in main is changed?

QC 16.5 answer

1

The planetsMarkII variable received a copy of the planets array, so modifications to either array are independent of each other.

2

The terraform function could return the revised [8]string array, so that main could reassign planets to the new value. Lesson 17 on slices and lesson 26 on pointers present other alternatives.

 

16.6. Arrays of arrays

You’ve seen arrays of strings, but you can also have arrays of integers, arrays of floating-point numbers, and even arrays of arrays. The 8 × 8 chessboard in the following listing is an array of arrays of strings.

Listing 16.8. Chessboard: chess.go
var board [8][8]string             1

board[0][0] = "r"
board[0][7] = "r"                  2

for column := range board[1] {
    board[1][column] = "p"
}

fmt.Print(board)

  • 1 An array of eight arrays of eight strings
  • 2 Places a rook at a [row][column] coordinate
Quick check 16.6

Q1:

Consider the game of Sudoku. What would the declaration look like for a 9 × 9 grid of integers?

QC 16.6 answer

1:

var grid [9][9]int

 

Summary

  • Arrays are ordered collections of elements with a fixed length.
  • Composite literals provide a convenient means to initialize arrays.
  • The range keyword can iterate over arrays.
  • When accessing elements of an array, you must stay inside its boundaries.
  • Arrays are copied when assigned or passed to functions.

Let’s see if you got this...

Experiment: chess.go

  • Extend listing 16.8 to display all the chess pieces at their starting positions using the characters kqrbnp for black pieces along the top and uppercase KQRBNP for white pieces on the bottom.
  • Write a function that nicely displays the board.
  • Instead of strings, use [8][8]rune to represent the board. Recall that rune literals are surrounded with single quotes and can be printed with the %c format verb.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset