web-dev-qa-db-fra.com

Différentes façons de passer des canaux comme arguments dans la fonction go (golang)

Je lisais du code go et disais quelques façons différentes de passer les canaux go. Peut-être que ce sont les mêmes mais je me demandais s'il y avait une différence car je n'ai pas pu trouver de documentation en ligne:

1)

func serve(ch <-chan interface{}){ //do stuff }

2)

func serve(ch chan<- interface{}){ //do stuff }

3)

func serve(ch chan interface{}){ //do stuff }

4)

func server(ch *chan interface{}){ //do stuff}

Je me demandais quelle était la différence entre eux et s'ils étaient juste des moyens équivalents de faire la même chose: passer un canal autour de différents goroutins.

Remarque: je suis conscient qu'il n'y a aucune raison de passer un pointeur vers un chan, une carte ou une tranche ou une valeur de fonction, car ce sont tous des types de référence qui contiennent en interne un pointeur (l'exception serait si vous voulez que l'appelé change l'en-tête du type de référence). La seule raison pour laquelle je l'ai fournie est pour être complète (c'est-à-dire pour fournir vraiment tous les moyens de passer un canal en tant que paramètre et pour poser une question qui, espérons-le, référence toutes les façons de le faire et les compare).

45
Charlie Parker

Il s'agit de différents types de canaux. Voir http://golang.org/ref/spec#Channel_types . Pour le truc du pointeur: Peu fréquent, mais peut être utile si vous voulez changer le canal depuis l'intérieur de la fonction (jamais vu cela dans la nature).

25
Volker

Je recommande toujours que la direction soit passée partout où cela est possible, par exemple.

func serve(ch <-chan SomeType) { /*do stuff*/ }

func serve(ch chan<- SomeType) { /*do stuff*/ }

En incluant la flèche <-chan ou chan<-, vous réalisez trois choses:

  • Vous indiquez clairement que le paramètre est un fin d'un canal.
  • Vous exprimez clairement qui fin est fourni.
  • Vous donnez plus d'informations au compilateur pour vérification. Si le corps de la fonction tente d'utiliser la mauvaise extrémité du canal, le compilateur peut générer une erreur.

Ce sont de bonnes raisons de montrer la fin du canal chaque fois que possible.

Votre troisième cas représente et non spécifiant la fin du canal. Cela permet d'accéder aux deux extrémités du canal, ce qui sera correct dans certains cas mais dans d'autres cas, peut entraîner des erreurs accidentelles.

Le quatrième cas, passant un pointeur sur un canal, est assez inhabituel et peut-être un peu étrange. Si vous vouliez changer le canal, il serait plus clair de l'inclure comme paramètre de retour à la place.

56
Rick-777

La règle de base: la flèche indique si les données entrent dans (sortie) ou sortent du canal (d'entrée). Aucune flèche n'est un canal à usage général.

chan <-          writing to channel (output channel)
<- chan          reading from channel (input channel)
chan             read from or write to channel (input/output channel)
21
smishra