Search⌘ K
AI Features

Strings Indexing, Length, and Traversal

Explore how to work with strings in Go by mastering indexing, length measurement, and traversal methods. Understand zero-based indexing, valid index ranges, and different iteration styles to efficiently process strings. This lesson helps you confidently manipulate text data for solving practical problems.

By now, you know that a string is an ordered sequence of text data. In Go, a string is stored as a read-only sequence of bytes, and for simple ASCII strings each byte corresponds to one character. It is a clean and simple idea, but an idea alone does not help you solve problems. The real question is how you actually work with a string once you have one. How do you reach into it and pull out a specific character? How do you know how many characters it contains? How do you move through it one step at a time? These are the basic operations that every string algorithm depends on, and getting comfortable with them is what turns the conceptual picture of strings into something you can actually use.

Indexing in strings

Each character in the string is associated with a specific position called an index. Indexing starts at zero, meaning the first character is at index 0, the second is at index 1, the third is at index 2, and so on. This is the same zero-based indexing that arrays and slices use.

Accessing individual characters

Because a Go string can be indexed like a sequence, accessing an individual byte works much like accessing an element in an array or slice. To retrieve the value at a specific index, write the name of the string followed by the index in square brackets. In the examples below, we convert the indexed byte to a string so it prints as a character.

Go (1.24.2)
package main
import "fmt"
func main() {
s := "hello"
fmt.Println(string(s[0])) // h
fmt.Println(string(s[1])) // e
fmt.Println(string(s[2])) // l
fmt.Println(string(s[3])) // l
fmt.Println(string(s[4])) // o
}

Indexing into a Go string gives you the byte stored at that position. For simple ASCII strings, that byte corresponds to the character at the same position. This operation takes constant time O(1)O(1) regardless of which index you use because the computer can calculate the exact memory address of any byte directly from its index, just as it does with arrays.

Counting from the end

Go does not support negative indices. An expression such as s[-1] is invalid. To access positions from the end of a string, calculate the non-negative index using the length. For example, the last character is at len(s) - 1, the second-to-last is at len(s) - 2, and so on.

Go (1.24.2)
package main
import "fmt"
func main() {
s := "hello"
fmt.Println(string(s[len(s)-1])) // o
fmt.Println(string(s[len(s)-2])) // l
fmt.Println(string(s[len(s)-3])) // l
fmt.Println(string(s[len(s)-4])) // e
fmt.Println(string(s[len(s)-5])) // h
}

Counting from the end is genuinely useful in practice. Many string problems require looking at the last character or working backward from the end. In Go, the usual way to do this is with expressions such as s[len(s) - 1] for the last character.

The len() built-in used here returns the number of bytes in a string. For the ASCII strings in this lesson, that is the same as the number of characters.

It helps to think of regular indices and from-end offsets as two different ways of describing the same positions in a string. For a string of length n, the character at index i can be described conceptually by the from-end offset i - n, but Go still requires you to convert that idea into a non-negative index before indexing.

String: h e l l o
Index: 0 1 2 3 4
From-end offset:-5 -4 -3 -2 -1

Both rows describe the same five positions. In Go, only the non-negative index row can be used directly in square brackets; the from-end offsets are a way to reason about positions.

Now, take a look at the following visualizer to better understand string indexing.

Length of a string

The length of a string is the total ...