4-bo‘lim

Satrlar, runalar va baytlar

Satrning ichki tuzilishi, bayt va runa farqi, UTF-8, strings paketi, strings.Builder va strconv bilan o'tkazish.

🕑 13 daqiqa o‘qish 📄 851 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Asosiy amallar
  2. Bayt va runa
  3. range bilan yurish
  4. Satr o'zgarmas
  5. strings paketi
  6. Satrlarni birlashtirish
  7. Son va satr orasida
  8. Sprintf - eng moslashuvchan yo'l
  9. Taqqoslash
  10. Xulosa

Go da satr - bu baytlar ketma-ketligi, va u o'zgarmas. Shu ikki jumla ko'p narsani tushuntiradi.

Asosiy amallar #

Go
package main

import (
    "fmt"
    "strings"
)

func main() {
    ism := "Husanboy"
    familiya := "Qodirov"

    toliq := ism + " " + familiya
    fmt.Println(toliq)
    fmt.Println(len(toliq))
    fmt.Println(strings.ToUpper(ism))
    fmt.Println(strings.Contains(toliq, "Qodir"))
}
Natija
Husanboy Qodirov
16
HUSANBOY
true

len - bu baytlar soni. Lotin harflari uchun u belgilar soniga teng, lekin doim emas - buni hozir ko'ramiz.

Bayt va runa #

Go
package main

import "fmt"

func main() {
    matn := "Go 🐹"

    fmt.Println("Baytlar:", len(matn))
    fmt.Println("Runalar:", len([]rune(matn)))

    fmt.Println(matn[0])
    fmt.Println(string(matn[0]))
}
Natija
Baytlar: 7
Runalar: 4
71
G

Bitta emoji to'rt bayt egallaydi, shuning uchun 4 ta belgi 7 ta baytga joylashgan.

matn[0] esa harfni emas, baytni qaytaradi - 71 bu G harfining kodi.

Satrni indeks bilan kesish xavfli

matn[i] har doim bayt beradi. Agar matnda faqat lotin harflari bo'lsa, bu muammo tug'dirmaydi.

Lekin emoji yoki boshqa alifbo bo'lsa, bitta belgi bir nechta baytdan iborat bo'ladi va matn[0] o'sha belgining faqat birinchi bo'lagini qaytaradi. Natijada buzuq belgi chiqadi.

To'g'ri yo'l ikkita:

  1. for i, r := range matn - Go belgilarni o'zi ajratadi.
  2. []rune(matn) - butun matnni belgilar massiviga aylantirish.

Ikkinchisi qulayroq, lekin yangi xotira talab qiladi.

TurAsliNimani bildiradi
byteuint8Bitta bayt (0-255)
runeint32Bitta belgi (Unicode kodi)

range bilan yurish #

Go
package main

import "fmt"

func main() {
    matn := "Go 🐹"

    for i, r := range matn {
        fmt.Printf("%d: %c (%d)\n", i, r, r)
    }
}
Natija
0: G (71)
1: o (111)
2:   (32)
3: 🐹 (128057)

Chap ustundagi sonlarga diqqat qiling: ular belgi tartibi emas, balki bayt o'rni. Uchta lotin belgisi 0, 1, 2 da turadi, emoji esa 3-baytdan boshlanadi va to'rt bayt egallaydi.

Shuning uchun matnda yana bir belgi bo'lganida, uning indeksi 4 emas, 7 bo'lardi. range bu hisobni o'zi yuritadi va har safar to'liq runa beradi - aynan shu kerak bo'ladi.

%c - belgini o'zini chiqaradi, %d esa uning raqamli kodini.

Nega Go UTF-8 ni tanlagan

Bu tasodif emas. UTF-8 ni Ken Tompson va Rob Payk o'ylab topgan - Go ning ikki yaratuvchisi, 1992-yilda.

Shuning uchun Go da UTF-8 qo'shimcha kutubxona emas, balki tilning o'ziga kiritilgan: manba fayllari UTF-8 da yoziladi, range esa runalarni o'zi ajratadi.

Boshqa ko'p tillar UTF-8 ni keyinchalik, og'riq bilan qo'shgan.

Satr o'zgarmas #

Go
package main

import "fmt"

func main() {
    matn := "salom"
    yangi := "S" + matn[1:]

    fmt.Println(matn)
    fmt.Println(yangi)

    harflar := []byte(matn)
    harflar[0] = 'S'
    fmt.Println(string(harflar))
}
Natija
salom
Salom
Salom

matn[0] = 'S' deb yozib bo'lmaydi - bu kompilyatsiya xatosi. O'zgartirish kerak bo'lsa, []byte yoki []rune ga o'tkaziladi.

matn[1:] - kesma (slice): birinchi baytdan keyingi hamma narsa. Kesmalarni 9-bo'limda batafsil ko'ramiz.

strings paketi #

Go
package main

import (
    "fmt"
    "strings"
)

func main() {
    matn := "  Namangan, Andijon, Farg'ona  "

    toza := strings.TrimSpace(matn)
    fmt.Printf("%q\n", toza)

    qismlar := strings.Split(toza, ", ")
    fmt.Println(qismlar, len(qismlar))

    fmt.Println(strings.Join(qismlar, " | "))
    fmt.Println(strings.HasPrefix(toza, "Naman"))
    fmt.Println(strings.Index(toza, "Andijon"))
    fmt.Println(strings.Replace(toza, "Andijon", "Buxoro", 1))
}
Natija
"Namangan, Andijon, Farg'ona"
[Namangan Andijon Farg'ona] 3
Namangan | Andijon | Farg'ona
true
10
Namangan, Buxoro, Farg'ona
FunksiyaNima qiladi
TrimSpaceChetdagi bo'shliqlarni oladi
SplitAjratgich bo'yicha bo'ladi
JoinBo'laklarni birlashtiradi
ContainsIchida bormi
HasPrefix / HasSuffixBoshlanadimi / tugaydimi
IndexBirinchi uchrash o'rni (yo'q bo'lsa -1)
ReplaceAlmashtiradi (oxirgi son - nechta)
FieldsBo'shliqlar bo'yicha bo'ladi
Replace da -1 hammasini almashtiradi

strings.Replace(matn, "a", "b", 1) faqat birinchisini almashtiradi. Hammasini almashtirish uchun oxirgi argument -1 bo'lishi kerak.

Buni unutmaslik uchun Go da alohida funksiya ham bor: strings.ReplaceAll(matn, "a", "b"). Amalda ko'pincha shu ishlatiladi.

Satrlarni birlashtirish #

Go
package main

import (
    "fmt"
    "strings"
)

func main() {
    shaharlar := []string{"Namangan", "Andijon", "Buxoro"}

    var quruvchi strings.Builder
    for i, sh := range shaharlar {
        if i > 0 {
            quruvchi.WriteString(", ")
        }
        quruvchi.WriteString(sh)
    }

    fmt.Println(quruvchi.String())
    fmt.Println(quruvchi.Len())
}
Natija
Namangan, Andijon, Buxoro
25
Siklda + bilan satr qo'shmang

Satr o'zgarmas bo'lgani uchun, natija += qism har safar butunlay yangi satr yaratadi va eskisini tashlaydi.

Uch element uchun bu sezilmaydi. Lekin o'n ming element uchun dastur sezilarli sekinlashadi, chunki ish hajmi element sonining kvadratiga mutanosib o'sadi.

strings.Builder esa ichida bitta bufer saqlaydi va unga qo'shib boradi. Agar ro'yxat tayyor bo'lsa, eng qisqa yo'l - strings.Join(shaharlar, ", ").

Son va satr orasida #

Go
package main

import (
    "fmt"
    "strconv"
)

func main() {
    son := 42
    matn := strconv.Itoa(son)
    fmt.Println(matn + "!")

    qayta, xato := strconv.Atoi("123")
    fmt.Println(qayta+1, xato)

    _, xato2 := strconv.Atoi("salom")
    fmt.Println("Xato:", xato2)

    kasr, _ := strconv.ParseFloat("3.14", 64)
    fmt.Println(kasr * 2)
}
Natija
42!
124 <nil>
Xato: strconv.Atoi: parsing "salom": invalid syntax
6.28

Bu yerda Go ning muhim odati birinchi marta ko'rinadi: Atoi ikkita qiymat qaytaradi - natija va xato.

Xato bo'lmasa, u nil bo'ladi. Xatolarni 14-bo'limda to'liq o'rganamiz.

FunksiyaYo'nalish
strconv.Itoaint -> string
strconv.Atoistring -> int
strconv.ParseFloatstring -> float64
strconv.FormatFloatfloat64 -> string
fmt.SprintfIstalgan tur -> string

Sprintf - eng moslashuvchan yo'l #

Go
package main

import "fmt"

func main() {
    ism := "Nodira"
    ball := 92.456

    xabar := fmt.Sprintf("%s: %.1f ball", ism, ball)
    fmt.Println(xabar)

    fmt.Printf("%-10s|%5d|\n", "chap", 42)
    fmt.Printf("%10s|%-5d|\n", "o'ng", 42)
}
Natija
Nodira: 92.5 ball
chap      |   42|
      o'ng|42   |

Sprintf - Printf bilan bir xil, faqat ekranga chiqarmaydi, balki satr qaytaradi.

ShablonMa'nosi
%.1fKasrdan keyin 1 raqam
%5dKamida 5 belgi, o'ngga tekislangan
%-10sKamida 10 belgi, chapga tekislangan

Taqqoslash #

Go
package main

import (
    "fmt"
    "strings"
)

func main() {
    a := "Salom"
    b := "salom"

    fmt.Println(a == b)
    fmt.Println(strings.EqualFold(a, b))
    fmt.Println(a < b)
    fmt.Println(strings.ToLower(a) == strings.ToLower(b))
}
Natija
false
true
true
true

Satrlarni ==, <, > bilan to'g'ridan-to'g'ri taqqoslash mumkin - Go da alohida equals metodi kerak emas.

a < b bayt kodlari bo'yicha solishtiradi. Katta harflar kichiklardan oldin kelgani uchun "Salom" < "salom" rost bo'ladi.

Amaliy topshiriq
  1. Ikki satrni + bilan birlashtiring va uzunligini chiqaring.
  2. Emoji qo'shilgan satrda len va len([]rune(...)) farqini ko'ring.
  3. range bilan har bir belgi va uning kodini chiqaring.
  4. Satrning birinchi harfini katta qilib o'zgartiring.
  5. strings.Split bilan ro'yxatni bo'lib, Join bilan qayting.
  6. Replace ni 1 va -1 bilan sinab, farqini ko'ring.
  7. strings.Builder bilan 5 ta so'zni birlashtiring.
  8. strconv.Atoi ga noto'g'ri satr berib, xatoni chiqaring.
  9. Sprintf bilan jadval ko'rinishida tekislangan qator yasang.
  10. EqualFold va == farqini ko'rsating.

Xulosa #

  • Satr - o'zgarmas baytlar ketma-ketligi; len baytlar sonini beradi.
  • byte - bitta bayt, rune - bitta belgi (Unicode kodi).
  • matn[i] bayt qaytaradi; belgilar uchun range yoki []rune ishlating.
  • UTF-8 ni Go ning ikki yaratuvchisi o'ylab topgan, shuning uchun u tilga chuqur kiritilgan.
  • strings paketida kundalik hamma amal bor; ReplaceAll - Replace(..., -1) ning qisqa shakli.
  • Siklda satr qo'shish uchun strings.Builder, tayyor ro'yxat uchun strings.Join.
  • strconv.Atoi ikkita qiymat qaytaradi: natija va xato.
  • Satrlarni == va < bilan to'g'ridan-to'g'ri taqqoslash mumkin.

Keyingi bo'limda shartlar va switch ni o'rganamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.