byte là alias của uint8 (1 byte thô); rune là alias của int32, đại diện cho một code point Unicode. String trong Go là chuỗi byte UTF-8 bất biến, không phải mảng ký tự.
Hệ quả:
- s[i] trả về byte, và len(s) đếm byte — không phải số ký tự.
- for i, r := range s lặp theo rune: giải mã UTF-8, i là offset byte, r là rune.
- []byte(s) copy byte thô; []rune(s) giải mã ra các code point.
go
s := "héllo"
len(s) // 6 — é chiếm 2 byte UTF-8
utf8.RuneCountInString(s) // 5 — số rune
for i, r := range s { // r là rune, i là offset byte
_ = i; _ = r
}