Sobes.tech
Middle

Ce se poate face cu un canal închis în Go?

sobes.tech AI

Răspuns de la AI

Când citiți dintr-un canal închis, puteți obține toate datele rămase care au fost scrise înainte de închidere. După ce canalul este golit, operațiile ulterioare de citire vor returna o valoare nulă a tipului elementului canalului și valoarea false ca a doua valoare returnată, indicând că canalul este închis.

Trimiterea de date către un canal închis va provoca o panică în timpul execuției.

Încercarea de a închide un canal deja închis va provoca, de asemenea, o panică în timpul execuției.

Poți verifica dacă un canal este închis folosind operatorul ok la citire:

package main

import (
	"fmt"
)

func main() {
	ch := make(chan int, 2)
	ch <- 1
	ch <- 2
	close(ch)

	// Citirea dintr-un canal închis până când este gol
	val1, ok1 := <-ch
	fmt.Printf("Valoare: %d, Ok: %t\n", val1, ok1) // Valoare: 1, Ok: true

	val2, ok2 := <-ch
	fmt.Printf("Valoare: %d, Ok: %t\n", val2, ok2) // Valoare: 2, Ok: true

	// Citirea după ce canalul este gol
	val3, ok3 := <-ch
	fmt.Printf("Valoare: %d, Ok: %t\n", val3, ok3) // Valoare: 0, Ok: false

	// Încercarea de a trimite către un canal închis (va provoca panic)
	// ch <- 3 // Ștergeți comentariul pentru a provoca panic

	// Încercarea de a închide un canal deja închis (va provoca panic)
	// close(ch) // Ștergeți comentariul pentru a provoca panic
}

Utilizarea range cu un canal închis permite citirea secvențială a datelor până când canalul este gol, moment în care bucla se termină automat.

package main

import (
	"fmt"
)

func main() {
	ch := make(chan int, 3)
	ch <- 10
	ch <- 20
	close(ch)

	// Utilizarea lui range cu un canal închis
	for val := range ch {
		fmt.Println(val) // Va afișa 10, apoi 20
	}
}