0Pricing
Go Academy · Lesson

Runes vs Bytes

Understand Go string internals.

Runes vs Bytes is a free Go Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Is a Go String?

In Go a string is an immutable sequence of bytes. The bytes usually hold UTF-8 encoded text, but Go never forces that.

  • You cannot change a string in place.
  • Its len counts bytes, not characters.
package main

import "fmt"

func main() {
    s := "Go"
    fmt.Println(s)
    fmt.Println(len(s))
}

Bytes Behind the Scenes

Indexing a string with s[i] returns a single byte (type byte, an alias for uint8).

For plain ASCII text each character is exactly one byte.

package main

import "fmt"

func main() {
    s := "ABC"
    fmt.Println(s[0])
    fmt.Println(s[1])
    fmt.Println(s[2])
}

A byte Is a Number

Because a byte is just a number, printing s[0] shows 65 (the ASCII code for A), not the letter.

To see the character, convert the byte back to a string.

package main

import "fmt"

func main() {
    s := "ABC"
    fmt.Println(string(s[0]))
}

What Is a rune?

A rune is an alias for int32 and represents a single Unicode code point.

  • One rune can span multiple bytes when encoded as UTF-8.
  • Use runes when you care about characters, not raw bytes.
package main

import "fmt"

func main() {
    var r rune = 'A'
    fmt.Println(r)
    fmt.Println(string(r))
}

Multibyte Characters

Non-ASCII characters take more than one byte in UTF-8. A string like "héllo" has more bytes than letters.

Notice how len reports the byte count, which is larger than the visible length.

package main

import "fmt"

func main() {
    s := "héllo"
    fmt.Println(len(s))
}

Ranging Over a String

A for range loop over a string decodes UTF-8 automatically. Each iteration yields:

  • the byte index where the rune starts,
  • the rune itself.
package main

import "fmt"

func main() {
    for i, r := range "héllo" {
        fmt.Println(i, string(r))
    }
}

Counting Characters Correctly

To count characters instead of bytes, convert the string to a []rune and take its length.

This gives the number of code points.

package main

import "fmt"

func main() {
    s := "héllo"
    runes := []rune(s)
    fmt.Println(len(runes))
}

Indexing by Rune

Once you have a []rune, you can index it to get the Nth character reliably, even with multibyte text.

package main

import "fmt"

func main() {
    runes := []rune("héllo")
    fmt.Println(string(runes[1]))
}

Strings to Bytes and Back

You can convert freely between a string and a []byte.

  • []byte(s) gives the raw bytes.
  • string(b) rebuilds the text.
package main

import "fmt"

func main() {
    b := []byte("Go")
    fmt.Println(b)
    fmt.Println(string(b))
}

Building a String from Runes

A slice of runes converts back into a string the same way. This is handy after editing characters individually.

package main

import "fmt"

func main() {
    runes := []rune{'G', 'o', '!'}
    fmt.Println(string(runes))
}

Bytes vs Runes Summary

Quick mental model:

  • byte = one raw byte (uint8), len(s) counts these.
  • rune = one Unicode code point (int32), range yields these.
  • Use []rune when counting or indexing characters.
package main

import "fmt"

func main() {
    s := "café"
    fmt.Println(len(s))
    fmt.Println(len([]rune(s)))
}

Quick Check

Test your understanding of runes and bytes.

Recap: Runes vs Bytes

You learned that Go strings are immutable byte sequences, usually UTF-8.

  • byte is a raw byte; len counts bytes.
  • rune is a Unicode code point; range decodes them.
  • Convert with []byte(s) and []rune(s) to work at the right level.
package main

import "fmt"

func main() {
    s := "Go語"
    fmt.Println("bytes:", len(s))
    fmt.Println("runes:", len([]rune(s)))
}

Frequently asked questions

Is the “Runes vs Bytes” lesson free?

Yes — the full text of “Runes vs Bytes” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.

What will I learn in “Runes vs Bytes”?

Understand Go string internals. You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Go Academy?

No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Runes vs Bytes” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Go Academy lesson?

Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Runes vs Bytes
  2. strings Package Functions
  3. strings.Builder
  4. Unicode and utf8
← Back to Go Academy