I was reading some go code and say a few different ways to pass go channels. Maybe they are the same but I was wondering if there is any difference since I couldn't find documentation online:
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}
I was wondering what the difference between them were and if they were just equivalent ways to do the same thing: pass a channel around different goroutines.
NOTE: I am aware that there is no reason to pass a pointer to a chan, map, or slice, or function value, since those are all reference types which internally contain a pointer (the exception would be if you want the callee to change the reference type header). The only reason I provided it is for completeness (i.e. to really provide every way a channel could be attempted to be passed as a parameter and to make on question that hopefully, references all ways to do this and compares them).
I always recommend that the direction is passed everywhere it is possible, e.g.
func serve(ch <-chan SomeType) { /*do stuff*/ }
func serve(ch chan<- SomeType) { /*do stuff*/ }
By including the arrow <-chan
or chan<-
, you are achieving three things:
These are good reasons to show the channel end whenever possible.
Your third case depicts not specifying the end of the channel. This allows both ends of the channel to be accessed, which will be correct in some cases but in other cases may lead to accidental errors.
The fourth case, passing a pointer to a channel, is quite unusual and perhaps a bit odd. If you wanted to change the channel, it would be clearer to include it as a return parameter instead.