Une réception n'écoute qu'une voix. Le vrai code en a plusieurs.A receive listens to one voice. Real code has several.
Au numéro précédent, un channel transmettait une valeur d'une main à l'autre. Mais une goroutine n'attend presque jamais une seule chose : elle guette un résultat, tout en restant à l'écoute d'une annulation, d'un délai, d'un second producteur. Avec un simple <-ch, on se fige sur la première voix et on devient sourd aux autres. Il faut un standard téléphonique : un point d'attente qui surveille plusieurs channels à la fois et donne la main au premier qui parle. C'est select.Last issue, a channel handed a value from one hand to another. But a goroutine almost never waits on a single thing: it watches for a result while staying alert to a cancellation, a deadline, a second producer. With a plain <-ch, you freeze on the first voice and go deaf to the rest. You need a switchboard: one waiting point that watches several channels at once and yields to whichever speaks first. That's select.
func wait(results <-chan int, done <-chan struct{}) int { res := <-results // on se fige sur UNE voix… return res // … et on n'entend ni l'annulation, ni l'horloge } // si results tarde, plus rien ne nous réveille
select met plusieurs réceptions en attente simultanée, puis débloque dès qu'une seule est prête — ici l'annulation arrive avant la donnée, et c'est elle qu'on sert. Les autres restent en attente, intactes, pour le prochain tour.select puts several receives on simultaneous watch, then unblocks the moment just one is ready — here cancellation arrives before the data, so that's the one served. The others stay waiting, untouched, for the next round.
« select attend le premier prêt, et n'en sert qu'un. » Tout le numéro tient là : il choisit un cas, exécute son corps, puis rend la main. Pour écouter en boucle, c'est à toi de l'envelopper dans un for — et c'est précisément là que se cachent les pièges."select waits for the first ready one, and serves only one." The whole issue lives there: it picks a case, runs its body, then hands back control. To listen on a loop, you wrap it in a for yourself — and that's exactly where the traps hide.
Un select n'aspire pas tous les channels prêts : il en choisit un, et un seul, par exécution. Les valeurs des autres cas ne sont pas consommées — elles restent dans leur channel. C'est la différence avec un range, qui draine un channel jusqu'au bout. Le select, lui, prend une décision ponctuelle ; l'orchestration dans la durée, c'est le for autour qui la porte.A select doesn't drain every ready channel: it picks one, and only one, per run. The other cases' values aren't consumed — they stay in their channels. That's the difference from a range, which drains one channel to the end. select makes a one-shot decision; sustained orchestration is carried by the for around it.