முக்கிய உள்ளடக்கத்திற்குச் செல்லவும்
தொகுதி 7 · பாடம் 3 இன் 5பாடத்திட்டத்தில் 33/50~12 min
தொகுதி பாடங்கள் (3/5)

`செலக்ட்`: மல்டிபிளெக்சிங் சேனல்கள்

select ஒரே நேரத்தில் பல சேனல் செயல்பாடுகளில் காத்திருக்கிறது. இது Go இன் switch ஆகும்: இது முதலில் செயல்பட உங்களை அனுமதிக்கிறது பல மத்தியில் சேனல் தயாராக உள்ளது.

தொடரியல்

Go
select {
case v := <-ch1:
    fmt.Println("ch1:", v)
case v := <-ch2:
    fmt.Println("ch2:", v)
case ch3 <- 99:
    fmt.Println("inviato su ch3")
case <-time.After(time.Second):
    fmt.Println("timeout")
default:
    fmt.Println("nessuno è pronto")
}

சொற்பொருள்:

  • அனைத்து வழக்குகளும் மதிப்பீடு செய்யப்படுகின்றன; தயாரான வழக்குகளில் ஒன்று மட்டுமே தேர்ந்தெடுக்கப்பட்டது.
  • பல வழக்குகள் தயாராக இருந்தால், தேர்வு ** போலி சீரற்ற** (வரிசைப்படுத்துதல் இல்லை).
  • எந்த வழக்கும் தயாராக இல்லை என்றால்: ஒன்று தயாராகும் வரை select தடுக்கப்படும்.
  • default இருந்தால்: எந்த வழக்கும் தயாராக இல்லாத போது அது உடனடியாக இயங்கும் (தடுக்காத தேர்ந்தெடுக்கவும்).

டைம்அவுட் பேட்டர்ன்

Go
select {
case res := <-fetch(url):
    use(res)
case <-time.After(2 * time.Second):
    log.Println("timeout: fetch troppo lento")
}

time.After(d) <-chan Timeஐ வழங்கும், அது dக்குப் பிறகு மதிப்பை உருவாக்கும். காத்திருப்பை கட்டுப்படுத்த இது ஒரு உன்னதமான வழி.

தடுக்காததை இயல்புநிலையாகத் தேர்ந்தெடுக்கவும்

Go
select {
case msg := <-ch:
    process(msg)
default:
    // niente da fare, prosegui
}

இது சேனலைத் தடுக்காமல் "வாக்கெடுப்பு" செய்கிறது. குறியீடு பாதைகளில் பயனுள்ளதாக இருக்கும் கட்டாயமாக காத்திருக்காமல் பதிலளிக்க வேண்டும்.

"முடிந்த சேனல்" முறை

ரத்துசெய்தல் சேனலுடன் select ஐ இணைக்கவும்:

Go
func worker(in <-chan Job, done <-chan struct{}) {
    for {
        select {
        case j := <-in:
            process(j)
        case <-done:
            return       // chi gestisce done segnala lo shutdown
        }
    }
}

close(done) ஒருங்கிணைப்பாளரிடமிருந்து case <-done ஒவ்வொரு முறையும் தூண்டுகிறது காத்திருக்கும் goroutine: ஒருங்கிணைந்த பணிநிறுத்தம்.

தேர்ந்தெடுக்கப்பட்டவுடன் லூப்

Go
for {
    select {
    case v := <-input:
        if v == nil {
            return
        }
        handle(v)
    case <-time.After(5 * time.Second):
        keepAlive()
    case <-ctx.Done():
        return
    }
}

சர்வர்கள் மற்றும் தொழிலாளர்களுக்கான வழக்கமான "நிகழ்வு வளைய" முறை.

"முடக்கப்பட்ட" கேஸாக இல்லாத சேனல்

ஒரு மேம்பட்ட தந்திரம்: case <-ch உடன் ch == nil ஒருபோதும் தேர்ந்தெடுக்கப்பட்டது. ஒரு வழக்கை மாறும் வகையில் "முடக்க" இது உங்களை அனுமதிக்கிறது:

Go
var in chan int = source()
for {
    select {
    case v, ok := <-in:
        if !ok {
            in = nil    // disabilita questo case
            continue
        }
        handle(v)
    case <-ctx.Done():
        return
    }
}

in மூடப்பட்டிருக்கும் போது, நான் அதை ரத்து செய்கிறேன்: select தொடர்ந்து கையாளும் மற்ற வழக்குகள்.

முயற்சி செய்து பாருங்கள்

உடற்பயிற்சி#go.m7.l3.e1
முயற்சிகள்: 0ஏற்றுகிறது…

ch1 மற்றும் ch2 இலிருந்து பெறும் இரண்டு நிகழ்வுகளுடன் ஒரு தேர்வை செயல்படுத்தவும்; முதலில் வந்ததை அச்சிடுங்கள்.

எடிட்டரை ஏற்றுகிறது…
குறிப்பைக் காட்டு

தொடரியல் `தேர்ந்தெடு { வழக்கு ...: ... }` ஒரு சேனலுக்கு ஒரு வழக்கு.

3 முயற்சிகளுக்குப் பிறகு தீர்வு கிடைக்கும்

உடற்பயிற்சி#go.m7.l3.e2
முயற்சிகள்: 0ஏற்றுகிறது…

நேரம்.

எடிட்டரை ஏற்றுகிறது…
குறிப்பைக் காட்டு

`time.After(d)` என்பது d க்குப் பிறகு பெறும் சேனலாகும்.

3 முயற்சிகளுக்குப் பிறகு தீர்வு கிடைக்கும்

Quiz#go.m7.l3.e3
தயார்

தேர்ந்தெடுக்கப்பட்டதைத் தடுக்காதது எது?

Go
select { case v := <-ch: ... ??? }
பதில் விருப்பங்கள்

மறுபரிசீலனை

  • select பல சேனல் செயல்பாடுகளில் முதல் தயார்நிலைக்காக காத்திருக்கிறது.
  • பல தயாராக வழக்குகளில் போலி-சீரற்ற தேர்வு.
  • default → தடுக்காத தேர்வு (வாக்கெடுப்பு).
  • time.After(d) காலக்கெடுவுக்கு (லூப்களில் கசிவைக் கவனியுங்கள்: context ஐப் பயன்படுத்தவும்).
  • வடிவங்கள்: ஒரு வழக்கை முடக்க சேனல், நிகழ்வு லூப், nil சேனல்.
  • வெற்று select{} = நித்திய தொகுதி: கிட்டத்தட்ட எப்போதும் பிழை.