Go’da string bilan ishlash
string matn va ixtiyoriy baytlar ketma-ketligini saqlaydigan turdir. Foydalanuvchi nomi, URL, fayl yo‘li, JSON maydoni va HTTP sarlavhasi kabi qiymatlar dasturlarda ko‘pincha string ko‘rinishida uchraydi.
String bilan ishonchli ishlash uchun uch narsani farqlash muhim: baytlar, Unicode kod nuqtalari va foydalanuvchi ko‘radigan belgilar. Ular har doim bir xil sonni anglatmaydi.
String literal va o‘zgarmaslik
Ikki tirnoq ichidagi interpreted literal \n, \t va \" kabi escape ketma-ketliklarini talqin qiladi. Backtick ichidagi raw literal esa matnni deyarli yozilganicha saqlaydi va bir nechta qatorni qamrab olishi mumkin:
| main.go | |
|---|---|
Natija:
Bitta tirnoq ichidagi 'A' string emas, rune literaldir. rune bitta Unicode kod nuqtasini ifodalaydi va int32 turining boshqa nomidir.
Go stringi o‘zgarmas (immutable). Yaratilgan string ichidagi baytni almashtirib bo‘lmaydi:
text = "No" esa mumkin. Bu eski stringni o‘zgartirmaydi, text o‘zgaruvchisiga boshqa string qiymatini beradi.
String, byte va rune
String ixtiyoriy baytlarni saqlashi mumkin. Go matn uchun ko‘pincha UTF-8dan foydalanadi, lekin string qiymatining o‘zi uning ichidagi baytlar to‘g‘ri UTF-8 ekanini kafolatlamaydi.
bytebitta baytni ifodalaydi vauint8turining boshqa nomidir;runeUnicode kod nuqtasini ifodalaydi vaint32turining boshqa nomidir;- ASCII belgilar UTF-8da bir bayt, ko‘plab boshqa belgilar esa bir necha bayt egallaydi.
| main.go | |
|---|---|
Natijaning boshi:
len(text) belgilarni emas, baytlarni sanaydi. utf8.RuneCountInString() Unicode kod nuqtalarini sanaydi. range har safar bitta UTF-8 kodlangan runeni beradi, indeks esa shu runening boshlanish bayt o‘rnidir.
Info
Rune soni ham foydalanuvchi ko‘radigan belgilar soniga har doim teng emas. Ayrim belgilar bir nechta Unicode kod nuqtasidan tuziladi. Go standart kutubxonasi grapheme clusterlarni alohida sanaydigan umumiy funksiya bermaydi.
Indeks orqali bayt olish
text[i] i-indeksdagi baytni byte sifatida qaytaradi:
| main.go | |
|---|---|
Natija:
71 — Gning UTF-8 va ASCII dagi bayt qiymati. %c shu qiymatni belgi sifatida chiqaradi. Indeks manfiy bo‘lsa yoki len(text)ga teng yoxud undan katta bo‘lsa, dastur runtime paytida panic qiladi.
Ko‘p baytli belgining faqat bir baytini olish to‘liq belgini bermaydi. Unicode matnni belgilar bo‘yicha qayta ishlash uchun range yoki []rune ishlatiladi:
| main.go | |
|---|---|
Natija:
[]rune(text) yangi rune slice va unga mos xotira yaratadi. Matnni faqat bir marta ketma-ket o‘qish kerak bo‘lsa, range odatda kamroq xotira talab qiladi.
Stringlarni birlashtirish va taqqoslash
Kichik miqdordagi stringlarni + bilan birlashtirish mumkin. == va != baytlar ketma-ketligining tengligini tekshiradi. <, >, <= va >= esa leksikografik, ya’ni bayt qiymatlari tartibida solishtiradi.
| main.go | |
|---|---|
Natija:
Katta siklda ko‘p bo‘lakni + bilan ketma-ket qo‘shish oraliq stringlar va xotira ajratishlarini ko‘paytirishi mumkin. Bunday holatda strings.Builder ishlatiladi:
| main.go | |
|---|---|
Natija:
strings.Builder qismlarni ichki bufferda yig‘adi. Tayyor natija String() bilan olinadi. Builderni nusxalab ishlatmaslik kerak.
Qism string olish
text[start:end] start indeksidan boshlab end indeksigacha, ammo endning o‘zini olmasdan baytlar oralig‘ini qaytaradi:
| main.go | |
|---|---|
Natija:
Chegaralar bayt indekslaridir. 0 <= start <= end <= len(text) bo‘lmasa, dastur panic qiladi. UTF-8 belgining o‘rtasidan kesish noto‘g‘ri kodlangan string hosil qilishi mumkin.
Unicode kod nuqtalari bo‘yicha kesish kerak bo‘lsa, avval []runega o‘tkaziladi:
Qism string odatda asl string ma’lumotining bir qismini ulashishi mumkin. Juda katta stringdan kichik qismni uzoq saqlash katta asosiy ma’lumotning xotirada qolishiga sabab bo‘lishi mumkin. Mustaqil nusxa zarur bo‘lsa, strings.Clone(part) ishlatiladi. Buni faqat xotira profili yoki aniq ownership talabi asoslaganda qo‘llash kerak.
strings paketi
Standart kutubxonadagi strings paketi qidirish, ajratish, birlashtirish, almashtirish va registrni o‘zgartirish funksiyalarini beradi.
Qidirish va tekshirish
Natija:
Contains() qism mavjudligini, Count() bir-birini qoplamaydigan uchrashuvlar sonini tekshiradi. Index() birinchi uchrashuvning bayt indeksini, topilmasa -1ni qaytaradi. Natijani indeks sifatida ishlatishdan oldin -1 emasligini tekshirish kerak.
strings.ContainsAny(text, "abc") ikkinchi argumentdagi runelardan kamida bittasi borligini tekshiradi. Butun qism stringni qidirish uchun esa Contains() kerak.
Ajratish va birlashtirish
| main.go | |
|---|---|
Natija:
Split() aynan berilgan ajratgich bo‘yicha bo‘ladi va bo‘sh elementlarni ham saqlashi mumkin. Fields() esa ketma-ket Unicode bo‘sh joylarni ajratgich deb oladi va bo‘sh elementlarni tashlaydi. Join() slice elementlarini berilgan ajratgich bilan birlashtiradi.
Almashtirish va takrorlash
| main.go | |
|---|---|
Natija:
Replace()ning oxirgi argumenti nechta uchrashuv almashtirilishini belgilaydi. -1 barcha uchrashuv degani; shu niyat uchun ReplaceAll() aniqroq o‘qiladi. Repeat() manfiy takrorlash sonida yoki natija juda katta bo‘lsa panic qilishi mumkin. Tashqi qiymatni oldindan tekshirish kerak.
Bosh va oxirni tozalash
| main.go | |
|---|---|
Natija:
TrimSpace() bosh va oxirdagi Unicode bo‘sh joylarni olib tashlaydi. Trim(value, ".") ikkinchi argumentni qism string emas, olib tashlanadigan runelar to‘plami sifatida talqin qiladi. Aniq prefiks yoki suffiksni bir marta olib tashlash uchun TrimPrefix() va TrimSuffix() ishlatiladi. Mos qism bo‘lmasa, ular asl stringni qaytaradi.
Katta-kichik harf va registrsiz taqqoslash
| main.go | |
|---|---|
Natija:
Faqat registrni e’tiborsiz qoldirib tenglikni tekshirish uchun ikkala tomonni ToLower() qilishdan ko‘ra EqualFold() maqsadni aniqroq ifodalaydi va Unicode case folding qoidalaridan foydalanadi.
strings.ToTitle() har bir runeni title case ko‘rinishiga o‘tkazadi; u gap yoki ismning faqat birinchi harfini katta qiladigan funksiya emas. Tabiiy tildagi sarlavha qoidalari tilga bog‘liq, shuning uchun bunday formatlash alohida talab asosida bajariladi.
strings.Map() bilan runelarni o‘zgartirish
strings.Map() har bir runega funksiya qo‘llab, yangi string qaytaradi. Funksiya manfiy qiymat qaytarsa, shu rune natijadan olib tashlanadi:
| main.go | |
|---|---|
Natija:
Bu usul matnni normalizatsiya qilish yoki ruxsat etilgan belgilarni qoldirishda foydali. Biroq real validatsiyada olib tashlangan belgilarni jim yashirish o‘rniga foydalanuvchiga xato qaytarish talab qilinishi mumkin.
UTF-8 to‘g‘riligini tekshirish
Fayl, tarmoq yoki boshqa tashqi manbadan olingan string noto‘g‘ri UTF-8 baytlarini saqlashi mumkin:
| main.go | |
|---|---|
Natija:
utf8.ValidString() string to‘g‘ri UTF-8 ekanini tekshiradi. Noto‘g‘ri ketma-ketlik bo‘ylab range qilinganda Go uning o‘rniga utf8.RuneError, ya’ni � runesini beradi. Protokol yoki fayl formati UTF-8 talab qilsa, qiymatni qayta ishlashdan oldin tekshirish kerak.
Keng tarqalgan xatolar
len()ni belgilar soni deb qabul qilish
len() baytlarni sanaydi. ASCII matnda bu ko‘pincha belgilar soniga teng ko‘rinadi, Unicode matnda esa farq qiladi. Kod nuqtalari uchun utf8.RuneCountInString(), foydalanuvchi ko‘radigan belgilar uchun esa talabga mos grapheme yechimi kerak.
Stringni bayt chegarasidan noto‘g‘ri kesish
text[a:b] chegaralari bayt indekslari. Unicode runening o‘rtasidan kesish noto‘g‘ri UTF-8 hosil qiladi. Rune bo‘yicha kesish zarur bo‘lsa, []runega o‘tkazing va qo‘shimcha xotira xarajatini hisobga oling.
strings.Trim()ni qism string olib tashlaydi deb o‘ylash
strings.Trim("abba", "ab") bosh va oxirdagi barcha a hamda b runelarini olib, bo‘sh string qaytaradi. Aniq "ab" qismi uchun TrimPrefix() yoki TrimSuffix() kerak.
Registrni o‘zgartirishni barcha matn qoidalariga yechim deb bilish
Unicode registri va tabiiy til qoidalari murakkab. Registrsiz texnik tenglik uchun EqualFold() mos. Foydalanuvchi ismi yoki lokal tilga xos saralash va formatlash uchun mahsulot talabi va maxsus kutubxona kerak bo‘lishi mumkin.
Xulosa
Go stringi o‘zgarmas baytlar ketma-ketligidir. len() baytlarni, range esa UTF-8 runelarni ko‘radi. Indekslash va kesish bayt chegaralari bilan ishlaydi. strings paketi qidirish, ajratish, birlashtirish, tozalash va almashtirish amallarini beradi. Unicode matnda byte, rune va foydalanuvchi ko‘radigan belgi farqini hisobga olish ishonchli kod yozish uchun muhim.
Keyingi darslarda stringlarni array va slice qiymatlari bilan birga qayta ishlashni ko‘ramiz.