Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing parameters to function closure

Tags:

closures

go

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.

like image 767
Dave Avatar asked May 12 '15 06:05

Dave


People also ask

How do you pass closure to a 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”.

Can a closure be assigned to a variable?

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.


1 Answers

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

like image 183
ANisus Avatar answered Sep 30 '22 10:09

ANisus