6-bo‘lim
Sikllar
for ning to'rt shakli, range bilan yurish, son bo'yicha sikl, break va continue, yorliqlar hamda ichma-ich sikllar.
Ushbu bo‘lim mundarijasi
Go da bitta sikl kalit so'zi bor: for. while, do-while,
foreach - hech biri yo'q.
Ularning o'rniga for bir necha shaklda yoziladi.
Klassik shakl #
package main
import "fmt"
func main() {
jami := 0
for i := 1; i <= 5; i++ {
jami += i
}
fmt.Println("Yig'indi:", jami)
}
Yig'indi: 15
Uch qism: boshlang'ich holat, shart, qadam. Ular orasida nuqtali vergul, atrofida esa qavs yo'q.
while shakli #
package main
import "fmt"
func main() {
qoldiq := 100
for qoldiq > 0 {
qoldiq -= 30
}
fmt.Println("Qoldiq:", qoldiq)
son := 1
for son < 100 {
son *= 2
}
fmt.Println("Birinchi 100 dan katta daraja:", son)
}
Qoldiq: -20
Birinchi 100 dan katta daraja: 128
Faqat shart qoldirilsa, for xuddi boshqa tillardagi while kabi
ishlaydi.
Go jamoasi tilga har bir kalit so'zni qo'shishdan oldin "busiz ham bo'ladimi?" deb so'raydi.
for shart { } allaqachon while ning aynan o'zi. Alohida kalit
so'z qo'shish tilni kattalashtiradi, lekin yangi imkoniyat bermaydi.
Aynan shu mulohaza tufayli Go da atigi 25 ta kalit so'z bor.
Cheksiz sikl #
package main
import "fmt"
func main() {
hisob := 0
for {
hisob++
if hisob >= 3 {
break
}
}
fmt.Println("Sikl", hisob, "marta aylandi")
}
Sikl 3 marta aylandi
for { } - shartsiz sikl. Undan chiqish uchun break yoki return
kerak.
Bu shakl serverlarda juda ko'p ishlatiladi: dastur to'xtatilmaguncha so'rovlarni qabul qilib turadi.
Son bo'yicha sikl #
package main
import "fmt"
func main() {
kvadratlar := []int{}
for i := range 5 {
kvadratlar = append(kvadratlar, i*i)
}
fmt.Println(kvadratlar)
hisob := 0
for range 3 {
hisob++
}
fmt.Println("Takrorlandi:", hisob)
}
[0 1 4 9 16]
Takrorlandi: 3
for i := range 5 - 0 dan 4 gacha yuradi. Bu shakl Go 1.22
da qo'shilgan va eng qisqa yozuvni beradi.
O'zgaruvchi kerak bo'lmasa, for range 3 deb yozish mumkin - shunchaki
uch marta takrorlaydi.
for i := range 5 faqat Go 1.22 va undan keyingi versiyalarda
ishlaydi. Undan oldingi kodda klassik shakl yoziladi:
for i := 0; i < 5; i++ {
Agar go.mod faylingizda go 1.21 yozilgan bo'lsa, yangi shakl
ishlamaydi - Go modulning versiyasiga qarab qaror qiladi.
range bilan yurish #
package main
import "fmt"
func main() {
shaharlar := []string{"Namangan", "Andijon", "Buxoro"}
for i, shahar := range shaharlar {
fmt.Printf("%d: %s\n", i, shahar)
}
fmt.Println("---")
for _, shahar := range shaharlar {
fmt.Println(shahar)
}
}
0: Namangan
1: Andijon
2: Buxoro
---
Namangan
Andijon
Buxoro
range ikkita qiymat beradi: indeks va elementning o'zi.
Indeks kerak bo'lmasa, uning o'rniga _ yoziladi. Bu "bu qiymat
menga kerak emas" degani.
Agar for i, shahar := range ... deb yozib, i ni ishlatmasangiz,
dastur kompilyatsiya bo'lmaydi:
i declared and not used
Aynan shuning uchun _ belgisi kerak. U maxsus nom: unga qiymat
berish mumkin, lekin uni o'qib bo'lmaydi va u hech qanday xotira
egallamaydi.
| Nima bo'yicha | Birinchi qiymat | Ikkinchi qiymat |
|---|---|---|
slice / massiv | Indeks | Element |
string | Bayt o'rni | Runa |
map | Kalit | Qiymat |
| Kanal | Element | - |
| Butun son | 0 dan boshlab hisob | - |
Faqat indeks kerak bo'lsa #
package main
import "fmt"
func main() {
ballar := []int{85, 92, 78}
for i := range ballar {
ballar[i] += 5
}
fmt.Println(ballar)
}
[90 97 83]
Ikkinchi qiymatni butunlay tashlab ketish mumkin. Bu yerda bu muhim: elementni o'zgartirish kerak, shuning uchun indeks bo'yicha murojaat qilinmoqda.
Bu kod hech narsani o'zgartirmaydi:
for _, ball := range ballar {
ball += 5
}
ball - elementning nusxasi. Uni o'zgartirish asl slicega ta'sir
qilmaydi.
O'zgartirish kerak bo'lsa, yuqoridagi kabi ballar[i] orqali
murojaat qiling.
break va continue #
package main
import "fmt"
func main() {
sonlar := []int{4, 8, 15, 16, 23, 42}
for _, son := range sonlar {
if son > 15 {
fmt.Println("Birinchi katta son:", son)
break
}
fmt.Println("Tekshirildi:", son)
}
fmt.Println("---")
toqlar := []int{}
for i := 1; i <= 10; i++ {
if i%2 == 0 {
continue
}
toqlar = append(toqlar, i)
}
fmt.Println(toqlar)
}
Tekshirildi: 4
Tekshirildi: 8
Tekshirildi: 15
Birinchi katta son: 16
---
[1 3 5 7 9]
break siklni to'xtatadi, continue esa faqat joriy aylanishni
tashlab, keyingisiga o'tadi.
Yorliqlar #
package main
import "fmt"
func main() {
topildi := false
tashqi:
for i := 1; i <= 4; i++ {
for j := 1; j <= 4; j++ {
if i*j == 6 {
fmt.Printf("Topildi: %d * %d\n", i, j)
topildi = true
break tashqi
}
}
}
fmt.Println("Qidiruv tugadi:", topildi)
}
Topildi: 2 * 3
Qidiruv tugadi: true
Oddiy break faqat ichki siklni to'xtatadi. Ikkalasidan ham
chiqish uchun yorliq qo'yiladi.
continue ham yorliq bilan ishlaydi: continue tashqi tashqi
siklning keyingi aylanishiga o'tadi.
Yorliq ba'zan kerak, lekin u kodni o'qishni qiyinlashtiradi.
Ko'p hollarda ichki siklni alohida funksiyaga chiqarib, undan
return qilish tozaroq yechim bo'ladi. Shunda yorliq ham, qo'shimcha
bayroq o'zgaruvchisi ham kerak emas.
Funksiyalarni keyingi bo'limda o'rganamiz.
Ichma-ich sikllar #
package main
import (
"fmt"
"strings"
)
func main() {
for i := 1; i <= 3; i++ {
qatorlar := []string{}
for j := 1; j <= 3; j++ {
qatorlar = append(qatorlar, fmt.Sprintf("%2d", i*j))
}
fmt.Println(strings.Join(qatorlar, " "))
}
}
1 2 3
2 4 6
3 6 9
%2d - sonni kamida ikki belgi joyga, o'ngga tekislab chiqaradi.
Shuning uchun ustunlar to'g'ri turadi.
Sikl - ifoda emas #
Ba'zi tillarda sikldan qiymat olish mumkin. Go da esa for - faqat
buyruq, ifoda emas:
natija := for i := range 5 { } // xato
Natija yig'ish kerak bo'lsa, siklidan tashqarida o'zgaruvchi e'lon
qilib, ichida to'ldirasiz - yuqoridagi kvadratlar va toqlar
misollaridagi kabi.
Go da map yoki filter kabi tayyor funksiyalar ham yo'q. Bu
ataylab: jamoa tilni kichik saqlashni afzal ko'rgan. Generiklar
qo'shilgandan keyin (17-bo'lim) ularni o'zingiz yozishingiz mumkin.
Amaliy misol #
package main
import "fmt"
func main() {
ballar := []int{85, 92, 78, 95, 88}
jami := 0
engYuqori := ballar[0]
for _, ball := range ballar {
jami += ball
if ball > engYuqori {
engYuqori = ball
}
}
ortacha := float64(jami) / float64(len(ballar))
fmt.Println("Jami:", jami)
fmt.Printf("O'rtacha: %.1f\n", ortacha)
fmt.Println("Eng yuqori:", engYuqori)
}
Jami: 438
O'rtacha: 87.6
Eng yuqori: 95
E'tibor bering: float64(jami) / float64(len(ballar)) - ikkala
tomon ham aniq o'tkazilgan. Aks holda natija butun son bo'lib,
87.6 o'rniga 87 chiqardi.
- Klassik
forbilan 1 dan 10 gacha yig'indini hisoblang. - Xuddi shuni
whileshaklida yozing. for { }vabreakbilan cheksiz sikldan chiqing.for i := range 5shaklini sinab ko'ring.rangebilan ro'yxatni indeksi bilan chiqaring._ishlatib, indeksni tashlab keting.rangenusxa berishini isbotlang.continuebilan faqat toq sonlarni yig'ing.- Yorliq bilan ichma-ich sikldan butunlay chiqing.
- Ko'paytirish jadvalini tekislangan ustunlarda chiqaring.
Xulosa #
- Go da bitta sikl kalit so'zi bor -
for;whilevaforeachyo'q. - To'rt shakl: klassik,
whileshakli, cheksizfor { }varange. for i := range 5- Go 1.22 dan boshlab ishlaydi.rangeikki qiymat beradi; keraksizini_bilan tashlang - ishlatilmagan o'zgaruvchi xato.rangeelementning nusxasini beradi; o'zgartirish uchunroyxat[i]orqali murojaat qiling.breakvacontinueyorliq bilan ishlaydi, lekin ko'pincha alohida funksiya tozaroq yechim.for- buyruq, ifoda emas: natijani tashqaridagi o'zgaruvchiga yig'asiz.
Keyingi bo'limda funksiyalarni o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.