Skip to content

Instantly share code, notes, and snippets.

@slav
Created December 18, 2016 05:00
Show Gist options
  • Save slav/ca2ee333c29b8f76b557c9b10b371b52 to your computer and use it in GitHub Desktop.
Save slav/ca2ee333c29b8f76b557c9b10b371b52 to your computer and use it in GitHub Desktop.
Golang sending sending multiple values through channel
package main
import "fmt"
func f(c chan func() (int, string)) {
c <- (func() (int, string) { return 0, "s" })
}
func main() {
c := make(chan func() (int, string))
go f(c)
y, z := (<-c)()
fmt.Println(y)
fmt.Println(z)
}
@akhilko
Copy link

akhilko commented Dec 11, 2019

Hi, Slav,
thanks for the trick. I tried it and found that the two values are not handled atomically, so they get screwed when the pairs are sent in a rapid sequence. Fernand Galiana @derailed suggested to fix it with the following trick that seems to work:

c <- ( func (i int, s string) func() (int, string) {
              return func() (int, string) {
                              return i, s
                          }
           } (intCode, dataString) )

The rationale is that (unlike function arguments) values for externally defined variables in function body are sampled asynchronously. Therefore, shielding them with an additional function taking variables as arguments makes sampling synchronous.

@slav
Copy link
Author

slav commented Dec 13, 2019

Cool, thanks for sharing the idea.

@meetme2meat
Copy link

meetme2meat commented Jan 13, 2020

@akhilo Although I understand the explanation alright. But I'm really not sure how can it be non-atomic when the channel is returning a func and variable are inside the func body.

Can you please show me how did you test it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment