دروس الوحدة (4/5)
السلاسل والبايتات والرونية
في Go، string عبارة عن تسلسل غير قابل للتغيير من البايتات. سلسلة حرفية
تم ترميزها بـ UTF-8. rune هو اسم مستعار لـ int32 و
يمثل Unicode نقطة كود واحدة.
يعد فهم الفرق بين البايتات والرونية أمرًا ضروريًا تجنب الأخطاء عندما تحتوي السلسلة على لهجات أو رموز تعبيرية أو إيديوجرامات أو أي شيء آخر حرف غير ASCII.
string = بايت، وليس أحرف
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) يُرجع عدد البايتات، وليس الأحرف المرئية.
تؤدي الفهرسة s[i] إلى إرجاع البايت i (uint8)، وليس الحرف.
for range يكرر الأحرف الرونية
for i, r := range s يفك ترميز UTF-8 سريعًا: i هو إزاحة البايت
من بداية الرون، r هو الرون (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): فهرسة لكل حرف
التحويل الصريح: يخصص شريحة جديدة من الأحرف الرونية. مكلفة ولكن ضروري في بعض الأحيان:
runes := []rune("ciaò")
fmt.Println(len(runes)) // 4
fmt.Println(string(runes[3])) // òstring(runes) هو التحويل العكسي: يأخذ []rune وينتج
سلسلة UTF-8.
السلاسل غير قابلة للتغيير
s := "ciao"
// s[0] = 'C' // ERROR: cannot assign to s[0]للتحويل، قم بالتحويل إلى []byte أو []rune، قم بالتشغيل، قم بالتحويل مرة أخرى:
b := []byte(s)
b[0] = 'C'
s = string(b) // "Ciao"سلسلة
يعمل عامل التشغيل +، ولكن بالنسبة للعديد من التسلسلات في الحلقة، يتم استخدامه
strings.Builder (أكثر كفاءة، ويتجنب التخصيصات المتوسطة):
var sb strings.Builder
for i := 0; i < 5; i++ {
sb.WriteString("ab")
}
fmt.Println(sb.String()) // "ababababab"حزم مفيدة
strings:Contains،HasPrefix،Split،Join،ToUpper،Replace...strconv:Atoi،Itoa،ParseFloat،FormatInt...- محمي_INLINE_32: محمي_INLINE_33، محمي_INLINE_34، محمي_INLINE_35...
unicode/utf8:RuneCountInString(بديل لـlen([]rune(s))).
جربه
قم بتكرار السلسلة مع النطاق وطباعة الفهرس والرونية باستخدام %d %c.
إظهار التلميح
النطاق عبر سلسلة يُرجع إزاحة البايت + الرون.
الحل متاح بعد 3 من المحاولات
تحويل s إلى []rune وطباعة طوله بالأحرف.
إظهار التلميح
تحويل صريح: `[]رون (رونات)`.
الحل متاح بعد 3 من المحاولات
ما هو لين ("ciaò")؟
s := "ciaò"
fmt.Println(len(s))خلاصة
string= تسلسل بايتات غير قابل للتغيير، بترميز UTF-8.len(s)= بايت؛s[i]= البايت الأول (uint8).for i, r := range sيفك رموز الأحرف الرونية؛iهو إزاحة البايت.[]rune(s)للفهرسة حسب الحرف (مكلف، مخصص).- للتغيير: انتقل إلى
[]byteأو[]rune. - للتسلسل في حلقة:
strings.Builder. - حزم المفاتيح:
strings،strconv،unicode،unicode/utf8.