ZetCode

Go string

last modified July 9, 2020

Go string tutorial shows how to work with strings in Golang. It is a simple introduction to Go strings.

Go string

Go string is a read-only slice of bytes. Indexing strings yields bytes not characters. A string holds arbitrary bytes. (Not only UTF-8.) A character in string can take 1..3 bytes

Regular strings are created with double quotes; they can contain escape sequences such as \n or \t. Raw strings are created with backticks. Raw strings do not interprete escape sequences. Multiline strings are created with backticks.

Go source code is in UTF-8. Go string literals consist of UTF-8 sequences. These sequences represent Unicode code points. In Go, they are called runes.

Classic for loops iterate over bytes, while the for range loop decodes one UTF-8-encoded rune on each iteration.

Go string simple example

The following example is a simple example with strings.

simple.go
package main

import (
    "fmt"
)

func main() {

    w1 := "a red fox"

    fmt.Println(w1)

    w2 := w1 + " and a falcon"
    fmt.Println(w2)
}

We define a regular string and print it. Then we concatenate two strings.

w1 := "a red fox"

A regular string is placed between two double quote characters.

w2 := w1 + " and a falcon"

With the + operator, we add two strings.

$ go run simple.go
a red fox
a red fox and a falcon

This is the output.

Go compare strings

Strings are compared with the == operator. Case-insensitive comparisons are performed with the EqualFold function.

comparing.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    w1 := "Aikido"
    w2 := "aikido"

    if w1 == w2 {

        fmt.Println("the strings are equal")
    } else {

        fmt.Println("the strings are not equal")
    }

    
    if strings.EqualFold(w1, w2) {

        fmt.Println("the strings are equal")
    } else {

        fmt.Println("the strings are not equal")
    }
}

The example compares two strings in case-sensitive and case-insensitive manner.

$ go run comparing.go 
the strings are not equal
the strings are equal

This is the output.

Escape sequences in Go

Escape sequences are special characters that have a specific meaning when used within a string literal. For instance, the new-line \n escape sequence causes the next character to appear on a new line.

escapes.go
package main

import (
    "fmt"
)

func main() {

    w1 := "old falcon\tred fox\nfast dog\tlazy cat\n"
    fmt.Println(w1)

    w2 := "it was a \"great film\""
    fmt.Println(w2)
}

In the example, we use several escape sequences.

w1 := "old falcon\tred fox\nfast dog\tlazy cat\n"

The \n adds a new line and the \t a horizontal tab.

w2 := "it was a \"great film\""

Sometimes we want to print the double quote character. Since it is part of the Go syntax, we need to use the escape character to print it.

$ go run escapes.go
old falcon      red fox
fast dog        lazy cat

it was a "great film"

This is the output.

Go raw & multiline strings

Raw and multiline strings are created with backticks.

raw_multi.go
package main

import (
    "fmt"
)

func main() {

    w1 := "old falcon\tred fox\nfast dog\tlazy cat\n"
    fmt.Println(w1)

    w2 := `old falcon\tred fox\nfast dog\tlazy cat\n`
    fmt.Println(w2)

    sonnet55 := `
Not marble nor the gilded monuments
Of princes shall outlive this powerful rhyme,
But you shall shine more bright in these contents
Than unswept stone besmeared with sluttish time.
When wasteful war shall statues overturn,
And broils root out the work of masonry,
Nor Mars his sword nor war’s quick fire shall burn
The living record of your memory.
’Gainst death and all-oblivious enmity
Shall you pace forth; your praise shall still find room
Even in the eyes of all posterity
That wear this world out to the ending doom.
So, till the Judgement that yourself arise,
You live in this, and dwell in lovers’ eyes.
    `

    fmt.Println(sonnet55)
}

The w2 string is a raw string and contains escape characters. They are printed rather than being interpreted. The sonnet55 is an example of a multiline strings in Go.

$ go run raw_multi.go
old falcon      red fox
fast dog        lazy cat

old falcon\tred fox\nfast dog\tlazy cat\n

Not marble nor the gilded monuments
Of princes shall outlive this powerful rhyme,
But you shall shine more bright in these contents
Than unswept stone besmeared with sluttish time.
When wasteful war shall statues overturn,
And broils root out the work of masonry,
Nor Mars his sword nor war’s quick fire shall burn
The living record of your memory.
’Gainst death and all-oblivious enmity
Shall you pace forth; your praise shall still find room
Even in the eyes of all posterity
That wear this world out to the ending doom.
So, till the Judgement that yourself arise,
You live in this, and dwell in lovers’ eyes.

This is the output.

Looping strings in Go

With the classic for loops we loop over bytes. The for range loops over runes.

looping.go
package main

import (
    "fmt"
)

func main() {

    w := "合気道"

    for idx, s := range w {

        fmt.Printf("The index number of %c is %d\n", s, idx)
    }

    fmt.Println("Bytes:")

    for i := 0; i < len(w); i++ {

        fmt.Printf("%x ", w[i])
    }

    fmt.Println()
}

The example uses both for loops.

$ go run looping.go
The index number of 合 is 0
The index number of 気 is 3
The index number of 道 is 6
Bytes:
e5 90 88 e6 b0 97 e9 81 93

This is the output.

Counting

The len function counts the number of bytes while the RuneCountInString counts the number of runes in a string.

counting.go
package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {

    w1 := "Aikido"

    fmt.Printf(w1 + "\n")
    fmt.Printf("Number of bytes %d\n", len(w1))
    fmt.Printf("Number of runes %d\n", utf8.RuneCountInString(w1))

    fmt.Printf("---------------\n")

    w2 := "合気道"

    fmt.Printf(w2 + "\n")
    fmt.Printf("Number of bytes %d\n", len(w2))
    fmt.Printf("Number of runes %d\n", utf8.RuneCountInString(w2))
}

The example prints the number of bytes and runes in a latin string and a Japanese hiragana.

$ go run counting.go
Aikido
Number of bytes 6
Number of runes 6
---------------
合気道
Number of bytes 9
Number of runes 3

This is the output.

Go runes

A Go rune is an alias to the int32 data type. It represents a Unicode CodePoint. The original rune word is a letter belonging to the written language of various ancient Germanic peoples, especially the Scandinavians and the Anglo-Saxons.

runes.go
package main

import (
    "fmt"
)

func main() {

    data := []rune {'♬', '♛', '♠', '🐘', '🐋'}

    for i, val := range data {

        fmt.Printf("Char %c Unicode: %U, Position: %d\n", val, val, i)
    }
}

In the example, we have an array of runes. The runes are emoji characters.

for i, val := range data {

    fmt.Printf("Char %c Unicode: %U, Position: %d\n", val, val, i)
}

We go through the array of runes and print them and their unicode code points and positions.

$ go run runes.go
Char ♬ Unicode: U+266C, Position: 0
Char ♛ Unicode: U+265B, Position: 1
Char ♠ Unicode: U+2660, Position: 2
Char 🐘 Unicode: U+1F418, Position: 3
Char 🐋 Unicode: U+1F40B, Position: 4

This is the output.

In this tutorial, we have covered strings in Golang.

List all Go tutorials.