Sobes.tech
Middle

Quelles sont les conséquences possibles lors de la lecture à partir d'un canal fermé en Go?

sobes.tech IA

Réponse de l'IA

La lecture d’un canal fermé renvoie immédiatement la valeur nulle du type d’éléments du canal sans blocage. Si un second paramètre booléen est présent, il sera false.

package main

import (
	"fmt"
)

func main() {
	ch := make(chan int, 1) // Canal tamponné
	ch <- 1
	close(ch)

	val, ok := <-ch // Lecture d’un canal fermé
	fmt.Printf("Valeur : %d, Ouvert : %t\n", val, ok) // Affichera "Valeur : 1, Ouvert : true"

	val, ok = <-ch // Lecture répétée du même canal fermé
	fmt.Printf("Valeur : %d, Ouvert : %t\n", val, ok) // Affichera "Valeur : 0, Ouvert : false"

	// Lectures supplémentaires du canal fermé
	val, ok = <-ch
	fmt.Printf("Valeur : %d, Ouvert : %t\n", val, ok) // Affichera "Valeur : 0, Ouvert : false"
}

Principales conséquences :

  • Obtention d’une valeur nulle : Le programme ne plantera pas, mais obtiendra la valeur nulle par défaut pour le type de données du canal.
  • Indicateur de fermeture : Le second paramètre booléen, s’il est utilisé, devient false, signalant que le canal est fermé et que la valeur reçue est nulle.
  • Lecture non bloquante : L’opération de lecture ne bloquera pas la goroutine.
  • Pas de panic : Contrairement à l’écriture dans un canal fermé, la lecture d’un canal fermé ne provoque pas de panic.

Comparaison de la lecture de canaux ouverts et fermés :

État du canal Opération Comportement Valeur retournée (si second paramètre)
Ouvert <-ch Blocage jusqu’à la réception ou la fermeture Valeur, true
Ouvert val, ok := <-ch Blocage jusqu’à la réception ou la fermeture Valeur, true
Fermé <-ch Obtention immédiate Valeur nulle
Fermé val, ok := <-ch Obtention immédiate Valeur nulle, false

L’utilisation du second paramètre booléen est la méthode recommandée pour déterminer si un élément réel a été reçu du canal ou si celui-ci est fermé.

package main

import (
	"fmt"
)

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

	for {
		val, ok := <-ch
		if !ok {
			fmt.Println("Le canal est fermé, sortie de la boucle.")
			break
		}
		fmt.Printf("Valeur reçue : %d\n", val)
	}
}

Ce comportement permet de terminer élégamment les goroutines qui lisent du canal après sa fermeture.