Reputation: 23
Can someone please help me understand how to interpret the following line of code in the function return - (_, _ <-chan interface{})
I understand that the function returns two channels. But I don't understand how it is achieved using the following (_, _ <-chan interface{}). What is the difference if I just swap it out for (<-chan interface{}, <-chan interface{})?
tee := func(
done <-chan interface{},
in <-chan interface{},
) (_, _ <-chan interface{}) {
out1 := make(chan interface{})
out2 := make(chan interface{})
go func() {
defer close(out1)
defer close(out2)
for val := range orDone(done, in) {
var out1, out2 = out1, out2
for i := 0; i < 2; i++ {
select {
case <-done:
case out1 <- val:
out1 = nil
case out2 <- val:
out2 = nil
}
}
}
}()
return out1, out2
}`
Upvotes: 2
Views: 192
Reputation: 1613
(_, _ <-chan interface{})
is equivalent to (<-chan interface{}, <-chan interface{})
. There are no differences, except source code length and readability.
(<-chan interface{}, <-chan interface{})
return value types.(ch1 <-chan interface{}, ch2 <-chan interface{})
to return same 2 channels.(ch1, ch2 <-chan interface{})
(_, _ <-chan interface{})
Voila! Readable pair of channels of the same type.
Upvotes: 2
Reputation: 4602
This is the func
declaration
FunctionType = "func" Signature .
Signature = Parameters [ Result ] .
Result = Parameters | Type .
Parameters = "(" [ ParameterList [ "," ] ] ")" .
ParameterList = ParameterDecl { "," ParameterDecl } .
ParameterDecl = [ IdentifierList ] [ "..." ] Type .
As you can see, the Result
is like method's parameters a Parameters
which in turn boils down to an IdentifierList
. There comes the blank identifier _
that can replace every identifier in the IdentifierList
.
The original author used this together with the "multiple identifiers declared to the same type" syntax to produce - as already mentioned - a strange to read declaration of two return values of the same type.
See https://golang.org/ref/spec#Function_declarations
You can also implement functions which "delete" parameters by using the blank identifier for them. May come handy, when you don't need the parameter of an interface you implement.
func foo(a string, _ int, b string) { ... }
The second parameter is not usable.
Upvotes: 0