Sobes.tech
Middle

Co lze dělat se zavřeným kanálem v Go?

sobes.tech AI

Odpověď od AI

Při čtení z uzavřeného kanálu můžete získat všechna zbývající data, která byla zapsána před uzavřením. Po vyprázdnění kanálu budou následující operace čtení vracet nulovou hodnotu typu prvku kanálu a hodnotu false jako druhou hodnotu, což naznačuje, že kanál je uzavřen.

Odeslání dat do uzavřeného kanálu způsobí za běhu pániku.

Pokud se pokusíte uzavřít již uzavřený kanál, také dojde k pániku.

Můžete zkontrolovat, zda je kanál uzavřený, pomocí operátoru ok při čtení:

package main

import (
	"fmt"
)

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

	// Čtení z uzavřeného kanálu, dokud není prázdný
	val1, ok1 := <-ch
	fmt.Printf("Hodnota: %d, Ok: %t\n", val1, ok1) // Hodnota: 1, Ok: true

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

	// Čtení po vyprázdnění kanálu
	val3, ok3 := <-ch
	fmt.Printf("Hodnota: %d, Ok: %t\n", val3, ok3) // Hodnota: 0, Ok: false

	// Pokus o odeslání do uzavřeného kanálu (způsobí panic)
	// ch <- 3 // Odkomentujte pro vyvolání panic

	// Pokus o uzavření již uzavřeného kanálu (způsobí panic)
	// close(ch) // Odkomentujte pro vyvolání panic
}

Použití range s uzavřeným kanálem umožňuje sekvenční čtení dat, dokud není kanál vyprázdněn, poté se cyklus automaticky ukončí.

package main

import (
	"fmt"
)

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

	// Použití range s uzavřeným kanálem
	for val := range ch {
		fmt.Println(val) // Vypíše 10, pak 20
	}
}