HowtoGo
Home / Basics / Bytes
Basics

Bytes

A byte is an alias for uint8. A []byte is a slice of them, the type most I/O and encoding functions read and write.

A byte holds a value from 0 to 255. Printing one prints its number, not a character.

var b byte = 65
fmt.Println(b) // 65

A single-quoted character constant like 'A' is its byte value. string(b) converts that number back to the one-character string it represents.

var b byte = 'A'
fmt.Println(b, string(b)) // 65 A

Converting a string to []byte copies its underlying bytes into a slice. Printing the slice shows each byte's number, not the text.

s := "Go"
b := []byte(s)
fmt.Println(b) // [71 111]

byte arithmetic wraps around at its range. 255 plus 1 doesn't produce a number outside the type; it wraps back to 0.

var b byte = 255
b++
fmt.Println(b)

Working with []byte

Indexing a string returns a single byte, not a character. é is two bytes in UTF-8, so s[1] is only the first of them.

s := "héllo"
fmt.Println(s[0], s[1])

[]byte can't be compared with ==. bytes.Equal compares length and content directly.

a := []byte("go")
b := []byte("go")
fmt.Println(bytes.Equal(a, b))

A plain loop over a []byte visits each byte in order. range over the original string decodes UTF-8 instead, visiting each rune.

s := "héllo"
b := []byte(s)

for i := 0; i < len(b); i++ {
    fmt.Printf("%d ", b[i])
}
fmt.Println()

for _, r := range s {
    fmt.Printf("%c ", r)
}

append grows a []byte one or more elements at a time, including another []byte spread with .... Frequent appends in a loop are better served by bytes.Buffer, covered in the bytes package reference.

var b []byte
b = append(b, 'g', 'o')
b = append(b, []byte("pher")...)
fmt.Println(string(b))

Putting it together

A byte value, a slice built from a string, a comparison, byte-by-byte versus rune-by-rune traversal, and a slice built up with append.

Terminal
$ go run main.go
71 111
true
104 195 169 108 108 111
h é l l o
gopher