37 / 68

select

Kanallarni tanlash operatori

Go dasturlash tilida select operatori bir nechta kanallar orasidan qaysi biri ma'lumot qabul qilishga yoki uzatishga tayyor bo'lsa, o'shasini tanlab darhol ishga tushirish uchun xizmat qiladi.

Sintaktik jihatdan u oddiy switch operatoriga juda o'xshaydi, biroq case shartlari faqat kanallar ustidagi amallardan iborat bo'ladi.


1. select sintaksisi

example.go
select {
case birinchiKanal := <-ch1:
    // ch1 tayyor bo'lganda ishlaydi
case ikkinchiKanal := <-ch2:
    // ch2 tayyor bo'lganda ishlaydi
}

2. Misol: Ikki kanal bilan select operatori

example.go
package main

import "fmt"

func channelNumber(number chan int) {
    number <- 15
}

func channelMessage(message chan string) {
    message <- "Go select operatori"
}

func main() {
    number := make(chan int)
    message := make(chan string)

    // Goroutinelarni ishga tushiramiz
    go channelNumber(number)
    go channelMessage(message)

    // Qaysi kanal birinchi tayyor bo'lsa, o'shani tanlaydi
    select {
    case firstChannel := <-number:
        fmt.Println("Raqam kanali ma'lumoti:", firstChannel)
    case secondChannel := <-message:
        fmt.Println("Xabar kanali ma'lumoti:", secondChannel)
    }
}

Ehtimoliy Natija:

kod
Xabar kanali ma'lumoti: Go select operatori

Agar bir vaqtning o'zida bir nechta kanal ma'lumot berishga tayyor bo'lsa, select ulardan birini tasodifiy (random) tarzda tanlab bajaradi.


3. Faqat bitta kanal tayyor bo'lgan holat

Agar kanallardan biri sekin ishlasa (masalan, tarmoq so'rovi yoki time.Sleep tufayli kechiksa), select kutib o'tirmasdan darhol tayyor bo'lgan boshqa kanalni ishga tushiradi:

example.go
package main

import (
    "fmt"
    "time"
)

func channelNumber(number chan int) {
    number <- 15
}

func channelMessage(message chan string) {
    // 2 soniyalik kechikish
    time.Sleep(2 * time.Second)
    message <- "Go select operatori"
}

func main() {
    number := make(chan int)
    message := make(chan string)

    go channelNumber(number)
    go channelMessage(message)

    select {
    case firstChannel := <-number:
        fmt.Println("Raqam:", firstChannel)
    case secondChannel := <-message:
        fmt.Println("Xabar:", secondChannel)
    }
}

Natija:

kod
Raqam: 15

Bu yerda message kanali 2 soniya kechikkani sababli, select darhol tayyor turgan number kanalini tanladi.


4. default holati (Bloklanishning oldini olish)

Agar barcha kanallar band yoki kutish rejimida bo'lsa, select qaysidir kanal tayyor bo'lguniga qadar dasturni bloklab (to'xtatib) qo'yadi.

Biroq dastur to'xtab qolmasdan o'z ishini davom ettirishi yoki foydalanuvchiga xabar berishi uchun default holatidan foydalanish mumkin:

example.go
package main

import (
    "fmt"
    "time"
)

func channelNumber(number chan int) {
    time.Sleep(2 * time.Second)
    number <- 15
}

func channelMessage(message chan string) {
    time.Sleep(2 * time.Second)
    message <- "Go select operatori"
}

func main() {
    number := make(chan int)
    message := make(chan string)

    go channelNumber(number)
    go channelMessage(message)

    select {
    case firstChannel := <-number:
        fmt.Println("Raqam:", firstChannel)
    case secondChannel := <-message:
        fmt.Println("Xabar:", secondChannel)
    default:
        // Hech bir kanal tayyor bo'lmaganda darhol ishlaydi
        fmt.Println("Kuting! Hozircha birorta kanal ma'lumot berishga tayyor emas.")
    }
}

Natija:

kod
Kuting! Hozircha birorta kanal ma'lumot berishga tayyor emas.

default holati mavjud bo'lsa, select zarracha ham kutmasdan darhol default blokidagi kodni bajaradi va dastur o'z ishini davom ettiradi.