Bài học theo mô-đun (4/5)
Chuỗi, byte và rune
Trong Go, string là một chuỗi byte không thể thay đổi. Chuỗi ký tự
được mã hóa bằng UTF-8. rune là bí danh của int32 và
đại diện cho một **điểm mã ** Unicode duy nhất.
Hiểu sự khác biệt giữa byte và rune là điều cần thiết để tránh lỗi khi một chuỗi chứa dấu trọng âm, biểu tượng cảm xúc, chữ tượng hình hoặc bất kỳ ký tự không phải ASCII.
string = byte, không phải ký tự
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) trả về số byte, không hiển thị ký tự.
Lập chỉ mục s[i] trả về byte thứ i (uint8), không phải ký tự.
for range lặp lại ngọc
for i, r := range s giải mã nhanh UTF-8: i là phần bù byte
khi bắt đầu chữ rune, r là chữ rune (int32):
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): lập chỉ mục theo từng ký tự
Chuyển đổi rõ ràng: phân bổ một lát rune mới. Tốn kém nhưng đôi khi cần thiết:
runes := []rune("ciaò")
fmt.Println(len(runes)) // 4
fmt.Println(string(runes[3])) // òstring(runes) là chuyển đổi nghịch đảo: nhận []rune và tạo ra
một chuỗi UTF-8.
Chuỗi là bất biến
s := "ciao"
// s[0] = 'C' // ERROR: cannot assign to s[0]Để biến đổi, hãy chuyển đổi thành []byte hoặc []rune, thao tác, chuyển đổi ngược lại:
b := []byte(s)
b[0] = 'C'
s = string(b) // "Ciao"Nối
Toán tử + hoạt động nhưng đối với nhiều phép nối trong vòng lặp, hãy sử dụng
strings.Builder (hiệu quả hơn, tránh phân bổ trung gian):
var sb strings.Builder
for i := 0; i < 5; i++ {
sb.WriteString("ab")
}
fmt.Println(sb.String()) // "ababababab"Gói hữu ích
strings:Contains,HasPrefix,Split,Join,ToUpper,Replace...strconv:Atoi,Itoa,ParseFloat,FormatInt...unicode:IsLetter,IsDigit,ToUpper...unicode/utf8:RuneCountInString(thay thế cholen([]rune(s))).
Hãy thử nó
Lặp lại chuỗi s với phạm vi và in chỉ mục và rune bằng cách sử dụng %d %c.
Hiển thị gợi ý
phạm vi trên một chuỗi trả về byte-offset + rune.
Giải pháp khả dụng sau 3 lần thử
Chuyển đổi s thành []rune và in độ dài của nó bằng ký tự.
Hiển thị gợi ý
Chuyển đổi rõ ràng: `[]rune(s)`.
Giải pháp khả dụng sau 3 lần thử
len("ciaò") là gì?
s := "ciaò"
fmt.Println(len(s))Tóm tắt lại
string= chuỗi byte bất biến, được mã hóa UTF-8.len(s)= byte;s[i]= byte thứ i (uint8).for i, r := range sgiải mã rune;ilà phần bù byte.[]rune(s)để lập chỉ mục theo ký tự (tốn kém, phân bổ).- Để thay đổi: đi qua
[]bytehoặc[]rune. - Để nối trong một vòng lặp:
strings.Builder. - Các gói key:
strings,strconv,unicode,unicode/utf8.