Lompati ke konten utama
Modul 4 · Pelajaran 4 dari 519/50 dalam kursus~12 min
Pelajaran modul (4/5)

String, byte, dan rune

Di Go, string adalah urutan byte yang tidak dapat diubah. String literal dikodekan dalam UTF-8. rune adalah alias untuk int32 dan mewakili satu titik kode Unicode.

Memahami perbedaan antara byte dan rune sangat penting hindari bug ketika string berisi aksen, emoji, ideogram, atau apa pun karakter non-ASCII.

string = byte, bukan karakter

Go
s := "ciaò"
fmt.Println(len(s))   // 5 — not 4!
fmt.Println(s[0])     // 99 ('c' as a byte)
fmt.Println(s[3])     // 195 (first byte of 'ò' in UTF-8)

len(s) mengembalikan jumlah byte, bukan karakter yang terlihat. Pengindeksan s[i] mengembalikan byte ke-i (uint8), bukan karakter.

for range mengulangi rune

for i, r := range s menerjemahkan kode UTF-8 dengan cepat: i adalah byte-offset dari awal rune, r adalah rune (int32):

Go
s := "ciaò"
for i, r := range s {
    fmt.Printf("%d %c (U+%04X)\n", i, r, r)
}
// 0 c (U+0063)
// 1 i (U+0069)
// 2 a (U+0061)
// 3 ò (U+00F2)   <- starts at byte 3, takes 2 bytes

[]rune(s): pengindeksan per karakter

Konversi eksplisit: mengalokasikan potongan rune baru. Mahal tapi terkadang diperlukan:

Go
runes := []rune("ciaò")
fmt.Println(len(runes))    // 4
fmt.Println(string(runes[3])) // ò

string(runes) adalah konversi terbalik: mengambil []rune dan menghasilkan string UTF-8.

String tidak dapat diubah

Go
s := "ciao"
// s[0] = 'C'   // ERROR: cannot assign to s[0]

Untuk bermutasi, konversikan ke []byte atau []rune, operasikan, konversikan kembali:

Go
b := []byte(s)
b[0] = 'C'
s = string(b)   // "Ciao"

Rangkaian

Operator + berfungsi, tetapi untuk banyak rangkaian dalam penggunaan loop strings.Builder (lebih efisien, menghindari alokasi perantara):

Go
var sb strings.Builder
for i := 0; i < 5; i++ {
    sb.WriteString("ab")
}
fmt.Println(sb.String())   // "ababababab"

Paket yang bermanfaat

  • strings: Contains, HasPrefix, Split, Join, ToUpper, Replace...
  • strconv: Atoi, Itoa, ParseFloat, FormatInt...
  • unicode: IsLetter, IsDigit, ToUpper...
  • unicode/utf8: RuneCountInString (alternatif dari len([]rune(s))).

Cobalah

Latihan#go.m4.l4.e1
Upaya: 0Memuat…

Ulangi string s dengan range dan cetak indeks dan rune menggunakan %d %c.

Memuat editor…
Tunjukkan petunjuk

rentang string mengembalikan byte-offset + rune.

Solusi tersedia setelah 3 upaya

Latihan#go.m4.l4.e2
Upaya: 0Memuat…

Ubah s menjadi []rune dan cetak panjangnya dalam karakter.

Memuat editor…
Tunjukkan petunjuk

Konversi eksplisit: `[]rune(s)`.

Solusi tersedia setelah 3 upaya

Quiz#go.m4.l4.e3
Siap

Apa itu len("ciaò")?

Go
s := "ciaò"
fmt.Println(len(s))
Pilihan jawaban

Rekap

  • string = urutan byte yang tidak dapat diubah, dikodekan UTF-8.
  • len(s) = byte; s[i] = byte ke-i (uint8).
  • for i, r := range s menerjemahkan rune; i adalah offset byte.
  • []rune(s) untuk mengindeks berdasarkan karakter (mahal, mengalokasikan).
  • Untuk bermutasi: melalui []byte atau []rune.
  • Untuk menggabungkan dalam satu lingkaran: strings.Builder.
  • Paket utama: strings, strconv, unicode, unicode/utf8.