I'm trying to understand the difference in Go between creating an anonymous function which takes a parameter, versus having that function act as a closure. Here is an example of the difference.
With parameter:
func main() { done := make(chan bool, 1) go func(c chan bool) { time.Sleep(50 * time.Millisecond) c <- true }(done) <-done }
As closure:
func main() { done := make(chan bool, 1) go func() { time.Sleep(50 * time.Millisecond) done <- true }() <-done }
My question is, when is the first form better than the second? Would you ever use a parameter for this kind of thing? The only time I can see the first form being useful is when returning a func(x, y)
from another function.
If we wanted to pass that closure into a function so it can be run inside that function, we would specify the parameter type as () -> Void . That means “accepts no parameters, and returns Void ” – Swift's way of saying “nothing”.
Said differently, a closure is a block of code that you can assign to a variable. You can then pass it around in your code, for instance to another function. The function then calls the closure and executes its code, as if the closure is an ordinary function.
The difference between using a closure vs using a function parameter has to do with sharing the same variable vs getting a copy of the value. Consider these two examples below.
In the Closure all function calls will use the value stored in i
. This value will most likely already reach 3 before any of the goroutines has had time to print it's value.
In the Parameter example each function call will get passed a copy of the value of i
when the call was made, thus giving us the result we more likely wanted:
Closure:
for i := 0; i < 3; i++ { go func() { fmt.Println(i) }() }
Result:
3
3
3
Parameter:
for i := 0; i < 3; i++ { go func(v int) { fmt.Println(v) }(i) }
Result:
0
1
2
Playground: http://play.golang.org/p/T5rHrIKrQv
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With