Go Tutorial · Go Basics · Lesson 8 of 30

Go Strings

String basics, the strings package, runes, formatting with fmt and strings.Builder.

Strings are UTF-8 bytes

len(s) counts bytes, not characters. Ranging over a string yields runes (Unicode code points):

Example 1
package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {
	s := "héllo"
	fmt.Println(len(s), utf8.RuneCountInString(s))
	for i, r := range "Go€" {
		fmt.Printf("%d:%c ", i, r)
	}
	fmt.Println()
	fmt.Println(s[0], string(s[0]), s[1:3] == "é")
	raw := `C:\path\no\escapes`
	fmt.Println(raw)
}

Output

6 5
0:G 1:o 2:€ 
104 h true
C:\path\no\escapes

Run this on your computer — see “Get Started” for setup.

The strings package

Example 2
package main

import (
	"fmt"
	"strings"
)

func main() {
	s := "  Go is fun, Go is fast  "
	t := strings.TrimSpace(s)
	fmt.Println(strings.ToUpper(t))
	fmt.Println(strings.Contains(t, "fun"), strings.HasPrefix(t, "Go"), strings.Index(t, "fast"))
	fmt.Println(strings.ReplaceAll(t, "Go", "Rust"))
	fmt.Println(strings.Split("a,b,c", ","), strings.Join([]string{"x", "y"}, "-"))
	fmt.Println(strings.Fields("  many   spaces here "), strings.Count(t, "Go"))

	var b strings.Builder
	for i := 1; i <= 3; i++ {
		fmt.Fprintf(&b, "[%d]", i)
	}
	fmt.Println(b.String())
}

Output

GO IS FUN, GO IS FAST
true true 17
Rust is fun, Rust is fast
[a b c] x-y
[many spaces here] 2
[1][2][3]

Run this on your computer — see “Get Started” for setup.

Formatting with fmt

fmt.Printf and fmt.Sprintf use verbs: %v (default), %+v (with field names), %T (type), %d, %s, %q (quoted), %.2f, %5d (width):

Example 3
package main

import "fmt"

func main() {
	type point struct{ X, Y int }
	p := point{1, 2}
	fmt.Printf("%v | %+v | %T\n", p, p, p)
	fmt.Printf("%q %5d| %-5d| %.2f %x %t\n", "go", 42, 42, 3.14159, 255, true)
	msg := fmt.Sprintf("%s has %d items", "cart", 3)
	fmt.Println(msg)
}

Output

{1 2} | {X:1 Y:2} | main.point
"go"    42| 42   | 3.14 ff true
cart has 3 items

Run this on your computer — see “Get Started” for setup.

For building long strings in a loop, use strings.Builder — it avoids copying.

Test yourself

What does len("héllo") return?

  1. 5
  2. 6
  3. 4
  4. It doesn't compile
Show answer

Answer: 6

len counts bytes, and é takes two bytes in UTF-8.